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" | +--------+ +------------------+
其次是参考变量。像任何引用变量一样,将它分配给另一个引用变量只会导致复制,而不是对象。两个参考变量指向相同的内存。
我想知道是否在第二行(String other = originalString)中进行多个赋值会导致任何性能损失,或者它与分配任何其他对象一样快。
您没有指定对象;你正在分配一个对象的引用。复制对字符串的引用不会比复制其他引用更昂贵。复制参考变量非常便宜。通常,您可以根据需要复制参考值以提高可读性和可理解性,而不会对性能产生重大影响。
字符串常量在Java不变。一旦创建了字符串文字,它就不能被修改并存储在字符串常量池中。下面是它如何在你的情况下工作:
String first = "Hello world";
新的字符串将创建在一个常量池和'第一'将指向它。
String second = first;
引用第一个和第二个引用都指向相同的字符串对象。
first = "Something else";
在这种情况下,String对象'Hello world'不会被修改。相反,一个新的对象'别的东西'将被创建,'第一'将开始指向它。而'第二'引用不断指向对象'Hello world'。
现在让我们说你创建一个新的参考是这样的:
String third = "Something else";
参考“第三”也将开始指向同一个对象作为第一个,即使你没有指派第一参考值它使用'='运算符。
*“字符串对象在java中是不可变的”*真实,但与OP发布的代码无关。它可能是一个像HashMap一样的可变对象,答案不会改变,因为OP的代码完全替代了对象引用,而不是试图改变它引用的对象。 *“一旦创建了一个字符串,它被存储在一个字符串常量池中”*不正确。这仅适用于'intern'字符串。字符串*文字*是'intern''d,而不是*所有*字符串。 –
是的,我同意你的意见。但事实上,我正在谈论字符串文字。 –
是的工程师是精确的。我在声明中添加了关键字'literal'。 :-) –
非常漂亮,+1 –