【问题标题】:Can I change String object's value passed to my method?我可以更改传递给我的方法的字符串对象的值吗?
【发布时间】:2012-01-03 03:58:31
【问题描述】:
我发现了以下问题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。有可能吗?
【问题讨论】:
标签:
java
string
parameters
pass-by-reference
immutability
【解决方案1】:
您不能更改foo 中errorText 的值,因为该方法当前已声明。即使您将字符串 errorText 的引用传递给 foo,Java Strings 也是不可变的——您无法更改它们。
但是,您可以使用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);
}
}
其他解决方案是使用包装类(创建一个类来保存您的字符串引用,并更改 foo 中的引用),或者只返回字符串。
【解决方案2】:
字符串值是不可变的——所以一旦你得到一个值,你就会被它困住。
【解决方案3】:
文字Strings被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 对象,这不会影响方法之外的任何内容。
不过,更一般地说,Strings 是不可变的;没有办法修改它们。
【解决方案4】:
您可以重新分配字符串引用:
String foo(String err) {
return "bla blah"
}
error = foo(error);
【解决方案5】:
要么使用方法的返回值,要么创建一个包装类。
让它返回值:
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());
}
【解决方案6】:
是的,您可以借助反射来更改此设置,但这是违反规则的。
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);
}