有一个面试题:
此语句中将创建多少个实例:
String str1 = new String ("abc")
答案是 2:str1
和"abc"
。
那是对的吗?
Only one instance will be created at run time . When the class is loaded the literal "abc"
will be interned in the String pool , though technically speaking JVM creates an instance of "abc"
and keeps it in the String pool . The expression new String("abc")
creates an instance of the String
.
A string literal is a reference to an instance of class String (§4.3.1, §4.3.3).
Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.
Also , read JLS 15.28
Compile-time constant expressions of type String are always "interned" so as to share unique instances, using the method String.intern.
Suggested Reading:
str1 is a variable reference, not Object and "abc" is String literal, not Object
I think, Only one instances is created on Heap
2是正确的,当使用“abc”Java const pool创建一个“abc”实例,使用new(“abc”),它在堆中创建另一个String实例。
否 - 在堆中只创建了一个实例。文字“abc”进入池。编译并执行 javap,您将只看到一个新的字节码。
考虑这个类-
public class InstanceTest {
public static void main(String... args){
String str1 =new String ("abc");
}
}
如果我们编译并执行-
javap -c InstanceTest
我们得到-
public class InstanceTest {
public InstanceTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String...);
Code:
0: new #2 // class java/lang/String
3: dup
4: ldc #3 // String abc
6: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: return
}
new关键字仅创建一个实例,并且在您的示例中,您将对象的引用放入 str1 (注意:否则它将被垃圾收集器删除)。
您将创建两个 String 实例。使用字符串构造函数而不是将它们声明为文字将始终创建不同的实例。
只需尝试以下代码:
String str = "abc";
String str2 = "abc";
String newString = new String(str);
System.out.println("Are " + str + " and " + newString + " the same instance? " + (str == newString));
System.out.println("Are " + str + " and " + str2 + " the same instance? " + (str == str2));
只会创建一个字符串实例,因为 java 编译器具有避免不必要地创建 String 对象的智能。它将文件编译为类文件,在该文件中尝试尽可能优化代码。
在此处阅读有关字符串实习的信息http://en.wikipedia.org/wiki/String_interning