String对象如何工作(如不可变对象)?

时间:2010-03-04 19:36:25

标签: java

我有以下两种情况:

String s = "aa";
s = s + " aa";
    System.out.println(s);
    //......

工作正常!它打印 aa aa 。 但是有一个问题:

String s = "aa";
this.addStringToStatement(s, " aa");
System.out.println(s);
//...
private void addStringToStatement(String statement, Object value) {
    statement += value;
}

打印: aa 。 是什么原因?? 谢谢!

8 个答案:

答案 0 :(得分:5)

这里要理解两个问题。

  1. String append运算符将创建一个新的不可变String对象。表达式s + value是内存中与s不同的对象。

  2. 在执行s addStringToStatement的函数tatement += value;中,您没有更改变量s的值,而是重新分配本地指针statement到一个新的String实例。

  3. 编辑:修正了常见的noob错误:在Java中,传递了对象引用,而不是对象本身。

答案 1 :(得分:4)

这是因为在Java中,引用是按值传递的。当你将s和“aa”作为两个参数传递时。

在方法声明中,变量(引用了s)被改变指向别的东西,即“aa aa”。请注意,只传递语句引用,s仍然指向“aa”。

因此,当你打印s时,你会得到预期的结果:)

答案 2 :(得分:3)

这是因为在Java中传递值是如何工作的,你需要做这样的事情:

String s = "aa";
s = this.addStringToStatement(s, " aa");
System.out.println(s);
//...
private string addStringToStatement(String statement, Object value) {
    statement += value;
    return statement;
}

答案 3 :(得分:1)

您必须返回“statement”变量。没有“this。*”部分。

String s = "aa";
s = addStringToStatement(s, " aa");
System.out.println(s);
//...
 private String addStringToStatement(String statement, Object value) {
    statement += value;
    return statement;
}

答案 4 :(得分:1)

Java中的字符串是不可变的。如果你有一个String s =“aa”,你只能引用JVM中的字符串“aa”。如果要将字符串“aa aa”分配给s,则只将引用(地址)分配给“aa aa”(JVM中的另一个字符串)为s,“aa”仍然潜伏在JVM中的某个位置。

语句“Java引用按值传递”有点令人困惑(如果是)。如果您使用StringBuilder sb并将此StringBuilder提供给函数,则引用将被“复制”但仍指向与sb相同的对象:

public static void main(String[] args) {
    final StringBuilder sb = new StringBuilder();
    f(sb);
    System.out.println(sb);
}

private static void f(final StringBuilder sb) {
    sb.append("aa aa");
}

答案 5 :(得分:1)

@FrankMeißner(新的,无法回复答案)

只是为了澄清String和StringBuilder之间的区别(如果有人读这个是混淆的),虽然两者都存储它们作为char []保存的CharSequence,但是String中的char []不能被更改,因此新的String具有为每个改变创建。对于StringBuilder,有类似StringBuilder.append(String)的方法可以更改StringBuilder的内部char [],因此如果调用StringBuilder.append(String),则不必为该方创建新对象。要更改的StringBuilder的内容。

根据FrankMeißner的例子,System.out.println(sb);将打印“aa aa”,因为方法append(String)是在StringBuilder上调用的。由于sb的身份没有改变,只有它的状态,所以final在这里不会受到伤害。

答案 6 :(得分:0)

+ =在字符串的情况下不会修改字符串本身但会产生新的字符串。在您的方法的情况下,您将此新字符串引用设置为局部变量(参数)

答案 7 :(得分:0)

Java引用按值传递。当您将String传递给方法并在其内部更改时,它会指向不同的String。您可以在追加后返回String或使用StringBuffer作为参数。