java - 字符串对象是不可变的,但引用变量是可变的。这意味着什么?

标签 java

我正在研究 Kathy Sierra Java 书。我遇到了一个这样的问题:

public class A {
    public static void main(String args[]){
        String s1 = "a";
        String s2 = s1;
        //s1=s1+"d";
        System.out.println(s1==s2);
    }
}

输出:true

这里有两点我不明白:

  1. 当我取消注释 s1 = s1 + "d" 时,输出更改为 false。如果我用包装器 Integerint 替换 String,也会发生同样的事情。
  2. 同样,当我更改我的代码以像这样使用 StringBuffer 时:

    StringBuffer sb = new StringBuffer("a"); 
    StringBuffer sb2 = sb;
    //sb.append("c");
    System.out.println(sb == sb2);
    

    现在输出没有改变,即即使我取消注释 sb.append 语句,它仍然是 true

我无法理解这种奇怪的行为。谁能给我解释一下。

最佳答案

s2 在第一种情况下是对 s1 的引用。在第二种情况下,+ 被翻译成 s1.concat("d"),它创建了一个新的字符串,所以引用 s1s2指向不同的字符串对象。

StringBuffer 的情况下,引用永远不会改变。 append 更改缓冲区的内部结构,而不是对其的引用。

关于java - 字符串对象是不可变的,但引用变量是可变的。这意味着什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30821444/

相关文章:

java - @ManyToOne 和@OneToOne 在同一实体上

java - 从 Map[String,Any] 类型的 Scala 映射中提取值,其中 Any 可以是 Map 本身

java - 缺少依赖项版本 - io.vertx :vertx-stack-depchain:jar is missing 为 'dependencies.dependency.version'

java - 如何在运行时获取 JUnit 4 中的测试用例名称?

java - 为什么这个自加等于0?

java - Java 8 中解析/处理 List<CompletableFuture<List<Object>>> 的最佳方法

java - 如何知道我的应用程序正在使用哪个端口

java - 在 libgdx java 中模拟弹跳的正确方法

java - MQQueueConnection.start不会持续监听新消息

java - glsl 片段着色器矩形不会显示