Java string value change in function

Yura picture Yura · Aug 15, 2010 · Viewed 42.4k times · Source

I have this very awkward question...

void changeString(String str){
    str = "Hello world":
}

main(){
    String myStr = new String("");
    changeString(myStr);
}

When main returns, the value is still "" and not "Hello world". Why is that?

Also, how do I make it work? Let's say I want my function changeString to change the string it got to "Hello world".

Answer

NullUserException picture NullUserException · Aug 15, 2010

Everyone explained why it doesn't work, but nobody explained how to make it work. Your easiest option is to use:

String changeString() {
    return "Hello world";
}

main() {

    String myStr = new String("");
    myStr = changeString();
}

Although the method name is a misnomer here. If you were to use your original idea, you'd need something like:

void changeString(ChangeableString str) {
    str.changeTo("Hello world");
}

main() {

    ChangeableString myStr = new ChangeableString("");
    changeString(myStr);
}

Your ChangeableString class could be something like this:

class ChangeableString {
    String str;
    
    public ChangeableString(String str) {
        this.str = str;
    }

    public void changeTo(String newStr) {
        str = newStr;
    }

    public String toString() {
        return str;
    }
}

A quick lesson on references:

In Java method everything is passed by value. This includes references. This can be illustrated by these two different methods:

void doNothing(Thing obj) {
    obj = new Something();
}

void doSomething(Thing obj) {
    obj.changeMe();
}

If you call doNothing(obj) from main() (or anywhere for that matter), obj won't be changed in the callee because doNothing creates a new Thing and assigns that new reference to obj in the scope of the method.

On the other hand, in doSomething you are calling obj.changeMe(), and that dereferences obj - which was passed by value - and changes it.