JVM如何处理字符串分配?

问题描述:

鉴于这种代码:JVM如何处理字符串分配?

String first = "Hello world"; 

String second = first; 

first = "Something else"; 

执行后,将变量second指向相同的内存实例变量first第一分配指出(相同的“Hello world”),还是会是一个完全不同的内存区域(也称为“Hello world”的另一个内存区域)?

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

执行后,将可变第二指向相同的存储器实例的变量首先在第一分配指出(相同的“世界你好”),或者将它是一个完全不同的存储器区域(另一存储区域哪个还说“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" | 
+--------+   +------------------+
+0

非常漂亮,+1 –

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

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

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

字符串常量在Java不变。一旦创建了字符串文字,它就不能被修改并存储在字符串常量池中。下面是它如何在你的情况下工作:

String first = "Hello world"; 

新的字符串将创建在一个常量池和'第一'将指向它。

String second = first; 

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

first = "Something else"; 

在这种情况下,String对象'Hello world'不会被修改。相反,一个新的对象'别的东西'将被创建,'第一'将开始指向它。而'第二'引用不断指向对象'Hello world'。

现在让我们说你创建一个新的参考是这样的:

String third = "Something else"; 

参考“第三”也将开始指向同一个对象作为第一个,即使你没有指派第一参考值它使用'='运算符。

+1

*“字符串对象在java中是不可变的”*真实,但与OP发布的代码无关。它可能是一个像HashMap一样的可变对象,答案不会改变,因为OP的代码完全替代了对象引用,而不是试图改变它引用的对象。 *“一旦创建了一个字符串,它被存储在一个字符串常量池中”*不正确。这仅适用于'intern'字符串。字符串*文字*是'intern''d,而不是*所有*字符串。 –

+0

是的,我同意你的意见。但事实上,我正在谈论字符串文字。 –

+1

是的工程师是精确的。我在声明中添加了关键字'literal'。 :-) –