Java字符串如何工作

时间:2013-05-08 04:09:36

标签: java string immutability

我试图准确理解Java字符串是如何不可变的。我知道这应该是一个简单的概念,但在阅读了几个在线网页后,我仍然不太了解。

我不明白Java字符串是如何“不可变的”。我目前有以下代码:

public static void main(String[] args) {

  String name = "Jacob Perkins";

  System.out.println( name );

  name = name + "!";

  System.out.println( name );

}

我的输出如下:

Jacob Perkins
Jacob Perkins!

如果字符串应该是不可变的,为什么会发生这种情况?为什么我能够为字符串重新赋值?

7 个答案:

答案 0 :(得分:34)

让图像为您解释:

String example

在左侧,您有变量,实际上是参考

  1. String name = "Jacob Perkins;"创建字符串“Jacob Perkins”,name指向它。
  2. name = name + "!";一个新的字符串“Jakob Perkins!”已创建,引用现在指向新String。但是,旧版本保持不变,因为String是不可变的。

答案 1 :(得分:5)

字符串本身一旦创建,就永远无法更改。您的代码示例所执行的操作是名称中的字符串替换为 new 字符串,该字符串是根据 name <的先前内容构建的/ strong>,还有一个感叹号。 ( name 的原始内容,不再被任何变量引用,最终将由垃圾收集器获取。)

如果您要检查已编译的代码(或使用调试器逐步执行它),您会发现已将name + "!"表达式编译为StringBuilder对象的创建以及该对象上的一些操作。

也就是说,字符串是不可变的,但变量 名称不是。它的值会发生变化,指向不同的字符串。字符串本身永远不会改变。

答案 2 :(得分:1)

只有变量引用发生变化,String对象才是不可变的。

在你的例子中,“Jacob Perkins”对象仍然存在,一个新对象“Jacob Perkins!”得到了。

name变量指向新对象。

答案 3 :(得分:1)

也许这会帮助你理解。

假设你有一个Point类(java.awt.Point)。 假设您有一个实例p:

Point p = new Point(0,0);

然后你创建一个新的变量y引用相同的对象p:

Point y = p;

如果更改p的值,也可以更改y。因为Point类是可变的。

p.setLocation(1,1);

它也使y引用位置1,1。

使用String类不会发生。

String a = "123";
String b = a;

如果你做a = a +“4”; a的新值将是“1234”,但b仍然是“123”;

他们引用的对象没有改变,只是a现在指向另一个对象。

答案 4 :(得分:0)

实际发生的是创建了3个String对象。 “Jacob Perkins”,“!”和“雅各布珀金斯!”你没有真正修改“Jacob Perkins”实例。您刚刚更改了名称变量的引用,从“Jacob Perkins”实例更改为“Jacob Perkins!”。

答案 5 :(得分:0)

String name = "Jacob Perkins";

String name2 = name + "!";
name.substring(5); // or wather syntax is

那些不会更改变量名称

答案 6 :(得分:0)

在Java中有引用,有值。

当你说

String foo = "John Smith";

foo是一个变量,持有一个引用。引用指向包含“John Smith”的对象或值。

变量持有的引用是可变的。我可以这样做:

foo = "Jack Smith";

我已经改变了参考文献。但是如果我写这样的代码:

String foo = "John Smith";
String bar = foo; //bar's reference is a copy of foo's reference - the same value
foo = "Jack Smith";
System.out.println(bar); //prints John Smith

我们看到即使我们改变了foo,bar也没有改变。为什么?简单地说,当我们写foo = "Jack Smith";时,我们使foo指向一个新的String。我们没有通过foo到达并修改字符串,因为 Java中没有方法变异,或者可以改变字符串。而是返回一个新的String,并使变量指向新的,也是不可变的String。这样,String变量'points'的对象永远不会被任何东西修改,只能通过该变量。这是它所保证的Java语言的一个重要属性。