28

I found the following question Is Java "pass-by-reference" or "pass-by-value"?.

I read almost all of it, but could not find out yet what should I do if I want the foo(-) method, to change my String's value? (maybe or not reference too, it doesn't matter to me).

void foo(String errorText){ 
    errorText="bla bla";
}

int main(){ 
    String error="initial"; 
    foo(error); 
    System.out.println(error);
}

I want to see bla bla on the console. Is it possible?

Community
  • 1
  • 1
merveotesi
  • 2,145
  • 15
  • 53
  • 84

6 Answers6

44

You can't change the value of errorText in foo as the method is currently declared. Even though you are passing a reference of the String errorText into foo, Java Strings are immutable--you can't change them.

However, you could use a StringBuffer (or StringBuilder). These classes can be edited in your foo method.

public class Test {
    public static void foo(StringBuilder errorText){ 
        errorText.delete(0, errorText.length());
        errorText.append("bla bla");
    }

    public static void main(String[] args) { 
        StringBuilder error=new StringBuilder("initial");
        foo(error); 
        System.out.println(error);
    }
}

Other solutions are to use a wrapper class (create a class to hold your String reference, and change the reference in foo), or just return the string.

Jack Edmonds
  • 31,931
  • 18
  • 65
  • 77
7

Either use the return value of the method or create a wrapper class.

Have it return the value:

String foo(String errorText){ 
    return "bla bla";
}

int main(){ 
    String error="initial"; 
    error = foo(error); 
    System.out.println(error);
}

Wrap the value in an object:

class StringWrapper {
    private String string;
    public StringWrapper(String s) {
        this.string = s;
    }
    public String getString() {
        return this.string;
    }
    public void setString(String s) {
        this.string = s;
    }
}

void foo(StringWrapper errorText){ 
    errorText.setString("bla bla");
}

int main(){ 
    StringWrapper error=new StringWrapper("initial"); 
    foo(error); 
    System.out.println(error.getString());
}
Erick Robertson
  • 32,125
  • 13
  • 69
  • 98
4

Yes you can change this with help of reflections but its against rule.

void foo(String errorText) {
    try {
        final Class<String> type = String.class;
        final java.lang.reflect.Field valueField = type.getDeclaredField("value");
        valueField.setAccessible(true);
        valueField.set(errorText, "bla bla".toCharArray());
    } catch (Exception e) {
    }

}

public static void main(String[] args) {
    String error = new String("initial");
    foo(error);
    System.out.println(error);
}
Saurabh Khare
  • 1,227
  • 13
  • 24
1

String values are immutable -- so once you get a value, you're stuck with it.

ryebr3ad
  • 1,228
  • 3
  • 12
  • 20
1

Literal Strings are treated specially by the Java language; your code is roughly equivalent to:

void foo(String errorText){ // at this point, errorText refers to the original string
    errorText=new String("bla bla"); // now it refers to a new string
}

int main(){ 
    String error=new String("initial"); // error is a reference to the original string
    foo(error); // pass a *copy* of the reference
    System.out.println(error);
}

In other words, you're just pointing the local reference errorText at a different String object, which affects nothing outside the method.

More generally, though, Strings are immutable; there's no way to modify them.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
0

You can reassign the String reference:

String foo(String err) {
  return "bla blah"
}

error = foo(error);
ewan.chalmers
  • 16,145
  • 43
  • 60