views:

123

answers:

9
private static void changeString(String s) {
    s = new String("new string");
}

public static void main(String[] args) {
    String s = new String("old string");
    changeString(s);
    System.out.println(s); // expect "new string"
}

How could I make the output of "new string" happen with s as the only argument to method changeString?

thanks.

+5  A: 

References in Java are passed by value, so even if you modify the reference inside the function, changes won't be reflected back to the calling function because what you modify inside the function is just a copy of the original reference not the original reference itself.

But you can return the new string from your changeString method instead of trying to modify the reference there(inside the function) itself.

Prasoon Saurav
+4  A: 

Only if you make the function

private static void changeString(String[] s) {
    s[0] = new String("new string");
}

String are immutable, and Java has no concept of a 'pointer-to-a-reference' as a first class datatype. If you don't like the above, you can make a little class containing a single String field.

bmargulies
A: 

This is not possible in Java as everything in Java is passed by value. In this case where the argument is an object reference it is the value of the reference that is passed into the method, not the reference itself.

Mark
+2  A: 

A: You can't, in Java object references are pass by value.

If you really need to, you can create a wrapper like this and use it the way you expected:

private static void changeString( _<String> str) {
     str.s("new string");
}

public static void main(String[] args) {
    _<String> s = new _<String>("old string");
    changeString(s);
    System.out.println(s); // prints "new string"
}
OscarRyz
A: 

Java does not allow out parameters like C#, so you will not be able to achieve this as such.

Victor Nicollet
+2  A: 

You can, of course, return the new string from your changeString method instead of trying to change it in place.

Alternately, you can create an object that wraps or contains a string, and pass that in. The ChangeString method would change the string that was internal to your object, and the main method would still be holding a reference to that object.

Otherwise, you can't do this. String is immutable, and java always passes objects as a value that is a pointer to a particular object. Change where you're pointing, and you aren't referencing the same object anymore.

JacobM
A: 

Strings are immutable in Java and parameters are passed by value so you can't change them (there is not equivalent to ref in C#). You can pass in a StringBuilder and change it's contents just as easily.

ruibm
+3  A: 

In Java arguments are passed by value, object arguments pass a reference to the object, this means that you can change the reference of the argument, but that does not change the object you passed the reference to. You have two possibilities, return the new object (preferred) or pass reference to a container that can receive the new reference (collection, array, etc.) For example:

private static String changeStringAndReturn(String s) {
    return new String("new string");
}
private static void changeStringInArray(String[] s) {
    if (null != s && 0 < s.length) {
        s[0] = new String("new string");
    }
}
rsp
In Java, arguments are passed by value!
Tarquila
The funny thing is the code is correct but the "documentation" is misleading. I wonder if the same happens with his code?
OscarRyz
@rsp-could you correct your documentation, since it is the accepted answer
TStamper
Fixed that, the object reference is passed by value.
rsp
Do not do the array thing though. Yes it works, but it is a "hack" and you should really be using a return value. If you need to change multiple things either rethink the problem (usually you do not have to) or create a class and return that class.
TofuBeer
@Tofu, I did say returning the new value is the preferred method. The array is, as mentioned, an example of a container. Passing a Map would be a better alternative. And as we are nitpicking today, returning a class would not help :-) you mean to say define a data-holder object class and return a data-holder instance with multiple values.
rsp
A: 

Its ugly but you could change the String to global static:

private static String s;

    private static void changeString(String t) {
        if(s.equals(t))
         s = new String("new string");
    }

    public static void main(String[] args) {
        s = new String("old string");
        changeString(s);
        System.out.println(s); // expect "new string"
    }
Laurence Dawson