【问题标题】:Java how are all String objects immutable? [duplicate]Java如何所有String对象都是不可变的? [复制]
【发布时间】:2019-12-25 16:59:17
【问题描述】:

如果这是一个明显的问题,我很抱歉,因为我是 Java 初学者。

String 对象是不可变的,这意味着它们无法更改。 所以如果你实例化:

String s = "hello";

然后改变s的内容,

s = "goodbye";

这是否意味着创建了一个新的 String 对象,也称为 s?原始变量 s 的值是否被更改?还是它的参考被改变了?提前感谢您,因为字符串不变性的概念让我感到困惑。

【问题讨论】:

  • 它的引用更改为不同的字符串对象,是的。并且添加两个字符串文字涉及第三个字符串结果
  • String s1 = "java"; s1.concat(" rules"); 这样做。并尝试System.out.println(s1)
  • 这能回答你的问题吗? Is a Java string really immutable?
  • 您混淆了变量和对象。变量有一个名字。物体没有。当您执行s = "hello" 时,您将对字符串对象“hello”的引用分配给名为s 的变量。当您执行s = "goodbye" 时,您将对另一个 字符串对象“hello”的引用分配给同一变量s。所以s 引用了对象“hello”,现在引用了对象“goodbye”。该代码中从未修改过任何对象。您只需将两个不同的对象分配给一个变量。

标签: java string object


【解决方案1】:

当你创建一个

String s = "hello";

在字符串池中查找后,java 在字符串池中创建一个新字符串并将该字符串的引用返回给 s。

现在当你改变 s 的内容时

s = "goodbye"; 

如果再见不在字符串池中,它将在字符串池中创建一个新字符串并返回新创建的字符串的引用。

所以你的问题的答案是字符串是不可变的。

如果你有很多操作要执行并且你的字符串内容会经常改变,你可以使用字符串生成器或字符串缓冲区,这些类是可变的。

【讨论】:

    【解决方案2】:

    您可以将不变性与 final 修饰符可以实现的互换。

    如果你声明一个变量为final,这意味着引用不能指向另一个实例而不是初始化:

    final String string = "A";
    string = "B";              // won't compile
    
    String anotherString = "A"
    anotherString = "B";       // this is okey
    

    不变性的要点是实例的 inner 字段不会改变。 String 的方法从原来的String 返回一个新的String,但它保持不变:

    String string = "A";
    string.toLowerCase();  // will be still "A"
    
    String anotherString = "A";
    String newString = anotherString.toLowerCase();
    
    // anotherString is "A"
    // newString is "a"
    

    注意使用不可变对象不需要final修饰符,但它用于在设计为不可变的对象中实现自身的不可变性。这个类是不可变的,因为bar 被实例化了一次并且永远不会改变:

    public class Foo {
    
        private final int bar;
    
        public Foo(int bar) {
            this.bar = bar;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-03-24
      • 1970-01-01
      • 2017-09-23
      • 2012-02-15
      • 1970-01-01
      • 1970-01-01
      • 2021-05-04
      • 2017-11-23
      • 1970-01-01
      相关资源
      最近更新 更多