0

Possible Duplicate:
How to implement int in/out params in java

Say I want to write a method that returns a User object, and also I want to modify UserStatus enumeration.

In c# I could do:

public User InsertNewUser(User newUser, out UserStatus userStatus)
{

}

The out (http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.80).aspx) basically gives me multiple objects that get 'returned'.

Curious if java has this?

Community
  • 1
  • 1
codecompleting
  • 9,251
  • 13
  • 61
  • 102
  • possible duplicate of [How to implement int in/out params in java](http://stackoverflow.com/questions/8355404/how-to-implement-int-in-out-params-in-java) and [How to create IN OUT or OUT parameters in Java](http://stackoverflow.com/questions/4455693/how-to-create-in-out-or-out-parameters-in-java) – Greg Hewgill Dec 05 '11 at 21:29
  • 1
    and if you're wondering *why*, see [Why does Java not use the out parameter in its language syntax while c# does?](http://stackoverflow.com/questions/1044452/why-does-java-not-use-the-out-parameter-in-its-language-syntax-while-c-sharp-doe) – Greg Hewgill Dec 05 '11 at 21:31

3 Answers3

1

You can't modify the incoming UserStatus reference, because Java is pass by value, but you can change its state if it's mutable.

public class UserStatus {

    private String status;

    public static void main(String [] args) {
        String name = ((args.length > 0) ? args[0] : "stas");
        User user = new User(name);
        UserStatus status = new UserStatus();
        System.out.println(String.format("before: user %s status %s\n", user.toString(), status.toString()));
        user = insertNewUser(user, status);
        System.out.println(String.format("after : user %s status %s\n", user.toString(), status.toString()));
    }

    public static User insertNewUser(User user, UserStatus status) {

        User newUser = new User(user.getName() + "-changed");


        status = new UserStatus("SUCCESS"); // Won't work as expected because Java is pass by value
        //status.setStatus("SUCCESS");  // Uncomment this and see that it's the only way to change the status flag

        return user;
    }

    public UserStatus() { this.status = "UNKNOWN"; }
    public UserStatus(String value) { this.status = value; }

    public String getStatus() { return this.status; }
    public void setStatus(String status) { this.status = status; }
    public String toString() { return this.status; }
}

class User {
    private final String name;

    public User(String name) { this.name = name; }


    public String getName() { return this.name; }
    public String toString() { return this.name; }
}
duffymo
  • 305,152
  • 44
  • 369
  • 561
  • 1
    java is only pass by value for primitive data types. All objects are pass by reference. – Stas Jaro Dec 05 '11 at 21:32
  • ok that's the same as c#, meaning I can change the state but not the reference. i.e. if I change UserStatus it will be reflected in the callers scope. I guess 'out' just makes this process/flow more visible and explicit. – codecompleting Dec 05 '11 at 21:34
  • @stas Java is pass by value only; even references gets passed by value. – Captain Giraffe Dec 05 '11 at 21:36
  • 1
    @stats Not exactly. Objects are passed by value too. Java manipulates objects 'by reference,' but it passes object references to methods 'by value. This link explains it in detail. http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html – Rondel Dec 05 '11 at 21:39
  • @duffmo: Well the reference(integer that points to the data in RAM), not the object, so the reference is still pointing to that object, so that makes no difference – Stas Jaro Dec 05 '11 at 21:41
  • 1
    @stas - incorrect. Java is pass by value for everything. That's why I wrote my response the way I did. – duffymo Dec 05 '11 at 21:42
  • @stas - It makes a *very* big difference. Here's the quote from James Gosling: "There is exactly one ParameterPassing mode in Java--pass by value--and that helps keep things simple." – duffymo Dec 05 '11 at 23:05
0

Java does not have anything similar. The variables will be passed by reference, so you can do:

UserStatus myStatus = new UserStatus();
User myUser = insertNewUser(someUser, myStatus);
System.out.println(myStatus);

Above, myStatus will be updated by your function, but as you can see, you need to initialize it before passing, unlike with a C# out variable.

Trevor Freeman
  • 7,112
  • 2
  • 21
  • 40
-1

If you want to modify userStatus the out is implied and not optional. If you were set userStatus to a new object, however it would refer to that new object.

Stas Jaro
  • 4,747
  • 5
  • 31
  • 53
  • Utterly wrong. Try it and see; I'll show you how wrong you are up above. – duffymo Dec 05 '11 at 23:24
  • If you create a new object inside the method, the reference goes out of scope when you exit the method. Nothing refers to it, so it's eligible for garbage collection. – duffymo Dec 05 '11 at 23:40