我可以更改传递给我的方法的String对象的值吗?

时间:2011-11-21 16:54:38

标签: java string parameters pass-by-reference immutability

我发现了以下问题Is Java "pass-by-reference" or "pass-by-value"?

我几乎阅读了所有内容,但是如果我想要foo(-)方法更改我的String,我还不知道该怎么办? (也许或不参考,对我来说无关紧要)。

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

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

我想在控制台上看到bla bla。有可能吗?

6 个答案:

答案 0 :(得分:36)

您无法更改errorTextfoo的值,因为当前声明了该方法。即使您将字符串errorText的引用传递给foo,Java String也是不可变的 - 您无法更改它们。

但是,您可以使用StringBuffer(或StringBuilder)。可以使用foo方法修改这些课程。

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);
    }
}

其他解决方案是使用包装类(创建一个类来保存String引用,并更改foo中的引用),或者只返回字符串。

答案 1 :(得分:7)

使用方法的返回值或创建包装类。

让它返回值:

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

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

将值包装在对象中:

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());
}

答案 2 :(得分:4)

是的,你可以通过反思来改变这一点,但是它违反了规则。

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);
}

答案 3 :(得分:1)

字符串值是不可变的 - 所以一旦你得到一个值,你就会坚持下去。

答案 4 :(得分:0)

Literal String由Java语言专门处理;你的代码大致相当于:

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);
}

换句话说,您只是将本地引用errorText指向不同的String对象,这会影响方法之外的任何内容。

更一般地说,String是不可变的;没有办法修改它们。

答案 5 :(得分:0)

您可以重新分配字符串引用:

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

error = foo(error);