Maybe this will aid your understanding:
String literal = "test";
String one = new String(literal);
String two = "test";
System.out.println(literal == two); //true
System.out.println(one == two); //false
In the example you posted:
String one = new String("test");
String two = "test";
the reference passed to the constructor String(String)
has the same value as the reference two
due to interning. However, the string itself (referenced by these two references) is used to construct a new object which is assigned to reference one
.
In this example, there are exactly two String
s created with the value "test": the one maintained in the constant pool and referenced whenever you use the literal "test"
in an expression, and the second one created by the "new" operator and assigned to the reference one
.
Edit
Perhaps you're confused about this statement:
When the compiler encounters a String literal, it checks the pool to see if an identical String already exists.
Note that this might be more clearly stated as:
When the compiler encounters a String literal, it checks to see if an identical String already exists in the pool.
Strings are only put in the pool when they are interned explicitly or by the class's use of a literal. So if you have, for example, this scenario:
String te = "te";
String st = "st";
String test = new String(te) + new String(st);
then while a String
will exist with the value test
, said String will not exist in the pool as the literal "test"
has never occurred.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…