任何人都可以通过此链接http://www.javatpoint.com/corejava-interview-questions-3
解释问题87和8987)以下代码中将创建多少个对象?
String s1 = "string1";
String s2 = "string1";
String s3 = "string1";
答案是:只有一个对象
89)以下代码中将创建多少个对象?
String s = new String("Welcome");
答案是:两个对象,一个在字符串常量池中,另一个在非池(堆)中。
答案 0 :(得分:6)
虽然String
是用Java编写的类,但它是一种特殊的类,它与JVM有一些特殊的关系。其中一个是字符串文字(用引号括起来的字符序列)。当JVM看到"abc"
时,它会执行以下操作:
String obj = stringLiteralsCache.get("abc");
if (obj == null) {
obj = new String("abc");
stringLiteralsCache.put("abc", obj);
}
因此,在您的第一个示例中,第一行导致创建新实例,但接下来的两行只是从缓存中获取已创建的实例。
但缓存仅适用于文字。当您显式调用构造函数时,它无法阻止创建新实例。因此,new String("Welcome")
创建了2个对象:一个来自文字Welcome
,因为它不在缓存中,其次是显式调用String构造函数。
答案 1 :(得分:2)
这里的主要原则是字符串在Java中是不可变的。这意味着一旦创建,它们就无法改变。
这允许JVM进行优化。因此,一个好的JVM将优化(87)创建一个对象。但是穷人可能不会。没有什么能让JVM做出这样的优化。 JLS不要求这样做。
因此(87)的明智答案可能是1,但不超过3。
(89)更难。在大多数情况下,您会发现在全局字符串池中创建了一个对象,而在正常内存中创建了第二个(由于您使用new
)。但是,我没有理由不能将这个优化为只有一个字符串s
直接引用全局字符串池。
因此(89)的明智答案可能是2,但可能只是1。
答案 2 :(得分:1)
在第一个语法(String string1= "string1";
)中,只为一个定义String .. = "....";
和一个指向它的引用变量创建了一个String对象。该对象在JVM维护的String常量池中创建。在第二种情况String s = new String("Welcome");
中,创建了两个String对象。由于调用new,因此在普通内存中创建一个String对象。另外,字符串常量" newstring"将被放置在String常量池中。
因此,当我们没有New Keyword时,我们只在String常量池中创建一个String对象。
更多信息请参阅:Create New Strings in normal memory and in string pool