JVM如何处理字符串赋值?

时间:2013-08-04 12:50:25

标签: java types jvm

鉴于此代码:

String first = "Hello world";

String second = first;

first = "Something else";

执行后,变量second是否指向变量first在第一个赋值中指向的相同内存实例(相同的“Hello world”)或者它是一个完全不同的内存region(另一个也称为“Hello world”的内存区域)?

我想知道在第二行(String other = originalString)中进行多次赋值是否会导致任何性能损失,或者它是否与分配任何其他对象一样快。

3 个答案:

答案 0 :(得分:10)

  

执行之后,变量second将指向变量在第一个赋值中首先指向的相同内存实例(相同的" Hello world")或者它将是一个完全不同的内存区域(另一个记忆区域也说" Hello world")?

相同的记忆区域。

以下是您在每个阶段所拥有的内容:

String first = "Hello world";

给你:

+-------+           +---------------+
| first |---------->| "Hello world" |
+-------+           +---------------+

然后

String second = first;
+--------+
| second |----\
+--------+     |     +---------------+
               +---->| "Hello world" | (same memory as above)
+--------+     |     +---------------+
| first  |----/
+--------+ 

然后

first = "Something else";
+--------+           +---------------+
| second |---------->| "Hello world" | (same memory as above)
+--------+           +---------------+
+--------+           +------------------+
| first  |---------->| "Something else" |
+--------+           +------------------+

答案 1 :(得分:2)

第二个是参考变量。与任何引用变量一样,将其分配给另一个引用变量只会导致复制引用,而不是对象。这两个引用变量指向同一个内存。

  

我想知道在第二行(String other = originalString)中进行多次赋值是否会导致任何性能损失,或者它是否与分配任何其他对象一样快。

你没有分配一个对象;你正在为一个对象分配一个引用。复制对字符串的引用并不比复制任何其他引用更昂贵。复制引用变量非常便宜。通常,您可以根据需要复制参考值,以提高可读性和可理解性,而不会对性能产生重大影响。

答案 2 :(得分:1)

字符串文字在java中是不可变的。创建字符串文字后,它将无法修改并存储在字符串常量池中。以下是它在您的情况下的工作方式:

String first = "Hello world";

将在常量池上创建新字符串,“first”将指向它。

String second = first;

第一个和第二个引用都将指向相同的字符串对象。

first = "Something else";

在这种情况下,不会修改String对象'Hello world'。相反,将创建一个新对象'Something',并且'first'将开始指向它。而“第二个”引用则指向对象“Hello world”。

现在假设你创建一个类似这样的新引用:

String third = "Something else";

引用“第三个”也将开始指向与第一个相同的对象,即使您没有使用“=”运算符为其指定第一个参考值。