What is the difference between “text” and new String(“text”)?
What is the difference between these two following statements?
String s = "text";
String s = new String("text");
java string
add a comment |
What is the difference between these two following statements?
String s = "text";
String s = new String("text");
java string
Related topic: JEP 192: String Deduplication in G1.
– Basil Bourque
Jun 7 at 22:49
add a comment |
What is the difference between these two following statements?
String s = "text";
String s = new String("text");
java string
What is the difference between these two following statements?
String s = "text";
String s = new String("text");
java string
java string
edited Feb 25 '15 at 22:13
nbro
5,52984793
5,52984793
asked Jun 16 '10 at 10:29
user368141
811275
811275
Related topic: JEP 192: String Deduplication in G1.
– Basil Bourque
Jun 7 at 22:49
add a comment |
Related topic: JEP 192: String Deduplication in G1.
– Basil Bourque
Jun 7 at 22:49
Related topic: JEP 192: String Deduplication in G1.
– Basil Bourque
Jun 7 at 22:49
Related topic: JEP 192: String Deduplication in G1.
– Basil Bourque
Jun 7 at 22:49
add a comment |
9 Answers
9
active
oldest
votes
new String("text");
explicitly creates a new and referentially distinct instance of a String
object; String s = "text";
may reuse an instance from the string constant pool if one is available.
You very rarely would ever want to use the new String(anotherString)
constructor. From the API:
String(String original)
: Initializes a newly createdString
object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since strings are immutable.
Related questions
- Java Strings: “String s = new String(”silly“);”
- Strings are objects in Java, so why don’t we use ‘new’ to create them?
What referential distinction means
Examine the following snippet:
String s1 = "foobar";
String s2 = "foobar";
System.out.println(s1 == s2); // true
s2 = new String("foobar");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
==
on two reference types is a reference identity comparison. Two objects that are equals
are not necessarily ==
. It is usually wrong to use ==
on reference types; most of the time equals
need to be used instead.
Nonetheless, if for whatever reason you need to create two equals
but not ==
string, you can use the new String(anotherString)
constructor. It needs to be said again, however, that this is very peculiar, and is rarely the intention.
References
- JLS 15.21.3 Reference Equality Operators == and !=
class Object
-boolean Object(equals)
Related issues
- Java String.equals versus ==
- How do I compare strings in Java?
3
If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
– Kaveesh Kanwal
Apr 16 '15 at 18:34
Why nobody answer preceding question?
– zeds
Dec 1 '15 at 5:56
2
@KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2"abc"
s. Only one of them will go to the String pool, and the other one will refer to it. Then there's thes
which will be proper new object.
– Kayaman
Mar 16 '16 at 11:21
1
@Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
– user968813
May 3 '16 at 7:38
There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
– user207421
Apr 24 at 11:45
add a comment |
String literals will go into String Constant Pool.
The below snapshot might help you to understand it visually to remember it for longer time.
Object creation line by line:
String str1 = new String("java5");
Using string literal "java5" in the constructor, a new string value is stored in string constant pool.
Using new operator, a new string object is created in the heap with "java5" as value.
String str2 = "java5"
Reference "str2" is pointed to already stored value in string constant pool
String str3 = new String(str2);
A new string object is created in the heap with the same value as reference by "str2"
String str4 = "java5";
Reference "str4" is pointed to already stored value in string constant pool
Total objects : Heap - 2, Pool - 1
Further reading on Oracle community
1
Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
– CoronaPintu
May 12 '14 at 8:25
2
yes i had check it will not change the value of str4
– CoronaPintu
May 12 '14 at 8:33
@Braj Can you provide documentation of your Answer’s assertion?
– Basil Bourque
Jul 1 '15 at 16:47
@Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
– Rahul Kurup
Aug 8 '15 at 10:52
Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
– user207421
Feb 7 '16 at 9:31
|
show 2 more comments
One creates a String in the String Constant Pool
String s = "text";
the other one creates a string in the constant pool ("text"
) and another string in normal heap space (s
). Both strings will have the same value, that of "text".
String s = new String("text");
s
is then lost (eligible for GC) if later unused.
String literals on the other hand are reused. If you use "text"
in multiple places of your class it will in fact be one and only one String (i.e. multiple references to the same string in the pool).
Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
– user207421
Jun 16 '10 at 10:38
@EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
– user159088
Jun 16 '10 at 10:43
add a comment |
JLS
The concept is called "interning" by the JLS.
Relevant passage from JLS 7 3.10.5:
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.
Example 3.10.5-1. String Literals
The program consisting of the compilation unit (§7.3):
package testPackage;
class Test {
public static void main(String args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
and the compilation unit:
package other;
public class Other { public static String hello = "Hello"; }
produces the output:
true true true true false true
JVMS
JVMS 7 5.1 says:
A string literal is a reference to an instance of class String, and is derived from a CONSTANT_String_info structure (§4.4.3) in the binary representation of a class or interface. The CONSTANT_String_info structure gives the sequence of Unicode code points constituting the string literal.
The Java programming language requires that identical string literals (that is, literals that contain the same sequence of code points) must refer to the same instance of class String (JLS §3.10.5). In addition, if the method String.intern is called on any string, the result is a reference to the same class instance that would be returned if that string appeared as a literal. Thus, the following expression must have the value true:
("a" + "b" + "c").intern() == "abc"
To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.
If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String.
Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.
Bytecode
It is also instructive to look at the bytecode implementation on OpenJDK 7.
If we decompile:
public class StringPool {
public static void main(String args) {
String a = "abc";
String b = "abc";
String c = new String("abc");
System.out.println(a);
System.out.println(b);
System.out.println(a == c);
}
}
we have on the constant pool:
#2 = String #32 // abc
[...]
#32 = Utf8 abc
and main
:
0: ldc #2 // String abc
2: astore_1
3: ldc #2 // String abc
5: astore_2
6: new #3 // class java/lang/String
9: dup
10: ldc #2 // String abc
12: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
15: astore_3
16: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_2
27: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
30: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
33: aload_1
34: aload_3
35: if_acmpne 42
38: iconst_1
39: goto 43
42: iconst_0
43: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
Note how:
0
and3
: the sameldc #2
constant is loaded (the literals)
12
: a new string instance is created (with#2
as argument)
35
:a
andc
are compared as regular objects withif_acmpne
The representation of constant strings is quite magic on the bytecode:
- it has a dedicated CONSTANT_String_info structure, unlike regular objects (e.g.
new String
) - the struct points to a CONSTANT_Utf8_info Structure that contains the data. That is the only necessary data to represent the string.
and the JVMS quote above seems to say that whenever the Utf8 pointed to is the same, then identical instances are loaded by ldc
.
I have done similar tests for fields, and:
static final String s = "abc"
points to the constant table through the ConstantValue Attribute
- non-final fields don't have that attribute, but can still be initialized with
ldc
Conclusion: there is direct bytecode support for the string pool, and the memory representation is efficient.
Bonus: compare that to the Integer pool, which does not have direct bytecode support (i.e. no CONSTANT_String_info
analogue).
add a comment |
Think of "bla"
being a magic factory like Strings.createString("bla")
(pseudo). The factory holds a pool of all strings yet created this way.
If it gets invoked, it checks if there is already string in the pool with this value. If true, it returns this string object, hence to strings obtained this way are indeed the same object.
If not, it creates a new string object internally, saves it in the pool and then returns it. Thus, when the same string value is queried the next time, it returns the same instance.
Manually creating new String("")
overrides this behaviour by bypassing the string literal pool. So equality should always be checked using equals()
which compares the character sequence instead of the object reference equality.
The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
– user207421
Feb 7 '16 at 9:20
add a comment |
One simple way to understand the difference is below:-
String s ="abc";
String s1= "abc";
String s2=new String("abc");
if(s==s1){
System.out.println("s==s1 is true");
}else{
System.out.println("s==s1 is false");
}
if(s==s2){
System.out.println("s==s2 is true");
}else{
System.out.println("s==s2 is false");
}
output is
s==s1 is true
s==s2 is false
Thus new String() will always create a new instance.
add a comment |
@Braj : i think u have mentioned the other way around. Please correct me if i am wrong
Object creation line by line:
String str1 = new String("java5")
Pool- "java5" (1 Object)
Heap - str1 => "java5" (1 Object)
String str2 = "java5"
pool- str2 => "java5" (1 Object)
heap - str1 => "java5" (1 Object)
String str3 = new String(str2)
pool- str2 => "java5" (1 Object)
heap- str1 => "java5", str3 => "java5" (2 Objects)
String str4 = "java5"
pool - str2 => str4 => "java5" (1 Object)
heap - str1 => "java5", str3 => "java5" (2 Objects)
str1
is not involved in the value ofstr2
orstr3
orstr4
in any way.
– user207421
Feb 7 '16 at 9:24
add a comment |
Although it looks the same from a programmers point of view, it has big performance impact. You would want to use the first form almost always.
add a comment |
String str = new String("hello")
It will check whether String constant pool already contains String "hello"?
If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.
An object will be created in a heap memory area and str
reference points to object created in heap memory location.
if you want str
reference to point object containing in String constant pool then one has to explicitly call str.intern();
String str = "world";
It will check whether String constant pool already contains String "hello"?
If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.
In both the above case, str
reference points to String "world"
present in Constant pool.
'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
– user207421
Feb 7 '16 at 9:28
Can you please explain what is wrong in this post clearly?
– Jayesh
Feb 7 '16 at 9:46
What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
– user207421
Oct 22 '16 at 7:22
@EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
– Jayesh
Oct 22 '16 at 7:43
You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
– user207421
Aug 23 '17 at 4:02
add a comment |
protected by ΦXocę 웃 Пepeúpa ツ Sep 8 '17 at 5:49
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
9 Answers
9
active
oldest
votes
9 Answers
9
active
oldest
votes
active
oldest
votes
active
oldest
votes
new String("text");
explicitly creates a new and referentially distinct instance of a String
object; String s = "text";
may reuse an instance from the string constant pool if one is available.
You very rarely would ever want to use the new String(anotherString)
constructor. From the API:
String(String original)
: Initializes a newly createdString
object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since strings are immutable.
Related questions
- Java Strings: “String s = new String(”silly“);”
- Strings are objects in Java, so why don’t we use ‘new’ to create them?
What referential distinction means
Examine the following snippet:
String s1 = "foobar";
String s2 = "foobar";
System.out.println(s1 == s2); // true
s2 = new String("foobar");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
==
on two reference types is a reference identity comparison. Two objects that are equals
are not necessarily ==
. It is usually wrong to use ==
on reference types; most of the time equals
need to be used instead.
Nonetheless, if for whatever reason you need to create two equals
but not ==
string, you can use the new String(anotherString)
constructor. It needs to be said again, however, that this is very peculiar, and is rarely the intention.
References
- JLS 15.21.3 Reference Equality Operators == and !=
class Object
-boolean Object(equals)
Related issues
- Java String.equals versus ==
- How do I compare strings in Java?
3
If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
– Kaveesh Kanwal
Apr 16 '15 at 18:34
Why nobody answer preceding question?
– zeds
Dec 1 '15 at 5:56
2
@KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2"abc"
s. Only one of them will go to the String pool, and the other one will refer to it. Then there's thes
which will be proper new object.
– Kayaman
Mar 16 '16 at 11:21
1
@Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
– user968813
May 3 '16 at 7:38
There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
– user207421
Apr 24 at 11:45
add a comment |
new String("text");
explicitly creates a new and referentially distinct instance of a String
object; String s = "text";
may reuse an instance from the string constant pool if one is available.
You very rarely would ever want to use the new String(anotherString)
constructor. From the API:
String(String original)
: Initializes a newly createdString
object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since strings are immutable.
Related questions
- Java Strings: “String s = new String(”silly“);”
- Strings are objects in Java, so why don’t we use ‘new’ to create them?
What referential distinction means
Examine the following snippet:
String s1 = "foobar";
String s2 = "foobar";
System.out.println(s1 == s2); // true
s2 = new String("foobar");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
==
on two reference types is a reference identity comparison. Two objects that are equals
are not necessarily ==
. It is usually wrong to use ==
on reference types; most of the time equals
need to be used instead.
Nonetheless, if for whatever reason you need to create two equals
but not ==
string, you can use the new String(anotherString)
constructor. It needs to be said again, however, that this is very peculiar, and is rarely the intention.
References
- JLS 15.21.3 Reference Equality Operators == and !=
class Object
-boolean Object(equals)
Related issues
- Java String.equals versus ==
- How do I compare strings in Java?
3
If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
– Kaveesh Kanwal
Apr 16 '15 at 18:34
Why nobody answer preceding question?
– zeds
Dec 1 '15 at 5:56
2
@KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2"abc"
s. Only one of them will go to the String pool, and the other one will refer to it. Then there's thes
which will be proper new object.
– Kayaman
Mar 16 '16 at 11:21
1
@Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
– user968813
May 3 '16 at 7:38
There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
– user207421
Apr 24 at 11:45
add a comment |
new String("text");
explicitly creates a new and referentially distinct instance of a String
object; String s = "text";
may reuse an instance from the string constant pool if one is available.
You very rarely would ever want to use the new String(anotherString)
constructor. From the API:
String(String original)
: Initializes a newly createdString
object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since strings are immutable.
Related questions
- Java Strings: “String s = new String(”silly“);”
- Strings are objects in Java, so why don’t we use ‘new’ to create them?
What referential distinction means
Examine the following snippet:
String s1 = "foobar";
String s2 = "foobar";
System.out.println(s1 == s2); // true
s2 = new String("foobar");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
==
on two reference types is a reference identity comparison. Two objects that are equals
are not necessarily ==
. It is usually wrong to use ==
on reference types; most of the time equals
need to be used instead.
Nonetheless, if for whatever reason you need to create two equals
but not ==
string, you can use the new String(anotherString)
constructor. It needs to be said again, however, that this is very peculiar, and is rarely the intention.
References
- JLS 15.21.3 Reference Equality Operators == and !=
class Object
-boolean Object(equals)
Related issues
- Java String.equals versus ==
- How do I compare strings in Java?
new String("text");
explicitly creates a new and referentially distinct instance of a String
object; String s = "text";
may reuse an instance from the string constant pool if one is available.
You very rarely would ever want to use the new String(anotherString)
constructor. From the API:
String(String original)
: Initializes a newly createdString
object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since strings are immutable.
Related questions
- Java Strings: “String s = new String(”silly“);”
- Strings are objects in Java, so why don’t we use ‘new’ to create them?
What referential distinction means
Examine the following snippet:
String s1 = "foobar";
String s2 = "foobar";
System.out.println(s1 == s2); // true
s2 = new String("foobar");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
==
on two reference types is a reference identity comparison. Two objects that are equals
are not necessarily ==
. It is usually wrong to use ==
on reference types; most of the time equals
need to be used instead.
Nonetheless, if for whatever reason you need to create two equals
but not ==
string, you can use the new String(anotherString)
constructor. It needs to be said again, however, that this is very peculiar, and is rarely the intention.
References
- JLS 15.21.3 Reference Equality Operators == and !=
class Object
-boolean Object(equals)
Related issues
- Java String.equals versus ==
- How do I compare strings in Java?
edited May 23 '17 at 11:54
Community♦
11
11
answered Jun 16 '10 at 10:30
polygenelubricants
280k101503591
280k101503591
3
If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
– Kaveesh Kanwal
Apr 16 '15 at 18:34
Why nobody answer preceding question?
– zeds
Dec 1 '15 at 5:56
2
@KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2"abc"
s. Only one of them will go to the String pool, and the other one will refer to it. Then there's thes
which will be proper new object.
– Kayaman
Mar 16 '16 at 11:21
1
@Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
– user968813
May 3 '16 at 7:38
There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
– user207421
Apr 24 at 11:45
add a comment |
3
If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
– Kaveesh Kanwal
Apr 16 '15 at 18:34
Why nobody answer preceding question?
– zeds
Dec 1 '15 at 5:56
2
@KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2"abc"
s. Only one of them will go to the String pool, and the other one will refer to it. Then there's thes
which will be proper new object.
– Kayaman
Mar 16 '16 at 11:21
1
@Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
– user968813
May 3 '16 at 7:38
There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
– user207421
Apr 24 at 11:45
3
3
If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
– Kaveesh Kanwal
Apr 16 '15 at 18:34
If i write: String s = new String("abc"); And now i write: String s = "abc"; Will String s = "abc"; create a new String literal in the String pool?
– Kaveesh Kanwal
Apr 16 '15 at 18:34
Why nobody answer preceding question?
– zeds
Dec 1 '15 at 5:56
Why nobody answer preceding question?
– zeds
Dec 1 '15 at 5:56
2
2
@KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2
"abc"
s. Only one of them will go to the String pool, and the other one will refer to it. Then there's the s
which will be proper new object.– Kayaman
Mar 16 '16 at 11:21
@KaveeshKanwal No, the literal won't be duplicated. As you can see there are 2
"abc"
s. Only one of them will go to the String pool, and the other one will refer to it. Then there's the s
which will be proper new object.– Kayaman
Mar 16 '16 at 11:21
1
1
@Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
– user968813
May 3 '16 at 7:38
@Kaveesh Kanwal - String s = new String("abc") will only create a new String object with value "abc". And the 2nd statement will check if there is any "abc" string literal is already present in String Pool or not. If already present then reference to the existing one is returned and if not then new literal ("abc") is created in String pool. Hope it resolves your query !!
– user968813
May 3 '16 at 7:38
There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
– user207421
Apr 24 at 11:45
There is no 'may' about it. The compiler must pool string literals. JLS 3.10.5.
– user207421
Apr 24 at 11:45
add a comment |
String literals will go into String Constant Pool.
The below snapshot might help you to understand it visually to remember it for longer time.
Object creation line by line:
String str1 = new String("java5");
Using string literal "java5" in the constructor, a new string value is stored in string constant pool.
Using new operator, a new string object is created in the heap with "java5" as value.
String str2 = "java5"
Reference "str2" is pointed to already stored value in string constant pool
String str3 = new String(str2);
A new string object is created in the heap with the same value as reference by "str2"
String str4 = "java5";
Reference "str4" is pointed to already stored value in string constant pool
Total objects : Heap - 2, Pool - 1
Further reading on Oracle community
1
Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
– CoronaPintu
May 12 '14 at 8:25
2
yes i had check it will not change the value of str4
– CoronaPintu
May 12 '14 at 8:33
@Braj Can you provide documentation of your Answer’s assertion?
– Basil Bourque
Jul 1 '15 at 16:47
@Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
– Rahul Kurup
Aug 8 '15 at 10:52
Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
– user207421
Feb 7 '16 at 9:31
|
show 2 more comments
String literals will go into String Constant Pool.
The below snapshot might help you to understand it visually to remember it for longer time.
Object creation line by line:
String str1 = new String("java5");
Using string literal "java5" in the constructor, a new string value is stored in string constant pool.
Using new operator, a new string object is created in the heap with "java5" as value.
String str2 = "java5"
Reference "str2" is pointed to already stored value in string constant pool
String str3 = new String(str2);
A new string object is created in the heap with the same value as reference by "str2"
String str4 = "java5";
Reference "str4" is pointed to already stored value in string constant pool
Total objects : Heap - 2, Pool - 1
Further reading on Oracle community
1
Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
– CoronaPintu
May 12 '14 at 8:25
2
yes i had check it will not change the value of str4
– CoronaPintu
May 12 '14 at 8:33
@Braj Can you provide documentation of your Answer’s assertion?
– Basil Bourque
Jul 1 '15 at 16:47
@Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
– Rahul Kurup
Aug 8 '15 at 10:52
Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
– user207421
Feb 7 '16 at 9:31
|
show 2 more comments
String literals will go into String Constant Pool.
The below snapshot might help you to understand it visually to remember it for longer time.
Object creation line by line:
String str1 = new String("java5");
Using string literal "java5" in the constructor, a new string value is stored in string constant pool.
Using new operator, a new string object is created in the heap with "java5" as value.
String str2 = "java5"
Reference "str2" is pointed to already stored value in string constant pool
String str3 = new String(str2);
A new string object is created in the heap with the same value as reference by "str2"
String str4 = "java5";
Reference "str4" is pointed to already stored value in string constant pool
Total objects : Heap - 2, Pool - 1
Further reading on Oracle community
String literals will go into String Constant Pool.
The below snapshot might help you to understand it visually to remember it for longer time.
Object creation line by line:
String str1 = new String("java5");
Using string literal "java5" in the constructor, a new string value is stored in string constant pool.
Using new operator, a new string object is created in the heap with "java5" as value.
String str2 = "java5"
Reference "str2" is pointed to already stored value in string constant pool
String str3 = new String(str2);
A new string object is created in the heap with the same value as reference by "str2"
String str4 = "java5";
Reference "str4" is pointed to already stored value in string constant pool
Total objects : Heap - 2, Pool - 1
Further reading on Oracle community
edited Jan 14 at 14:02
Lucky
10.4k1074113
10.4k1074113
answered May 8 '14 at 15:26
Braj
40.3k43658
40.3k43658
1
Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
– CoronaPintu
May 12 '14 at 8:25
2
yes i had check it will not change the value of str4
– CoronaPintu
May 12 '14 at 8:33
@Braj Can you provide documentation of your Answer’s assertion?
– Basil Bourque
Jul 1 '15 at 16:47
@Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
– Rahul Kurup
Aug 8 '15 at 10:52
Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
– user207421
Feb 7 '16 at 9:31
|
show 2 more comments
1
Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
– CoronaPintu
May 12 '14 at 8:25
2
yes i had check it will not change the value of str4
– CoronaPintu
May 12 '14 at 8:33
@Braj Can you provide documentation of your Answer’s assertion?
– Basil Bourque
Jul 1 '15 at 16:47
@Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
– Rahul Kurup
Aug 8 '15 at 10:52
Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
– user207421
Feb 7 '16 at 9:31
1
1
Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
– CoronaPintu
May 12 '14 at 8:25
Good answer.. but weant to know that now i am giong to change value of str1="java6" then it will change value of str4?
– CoronaPintu
May 12 '14 at 8:25
2
2
yes i had check it will not change the value of str4
– CoronaPintu
May 12 '14 at 8:33
yes i had check it will not change the value of str4
– CoronaPintu
May 12 '14 at 8:33
@Braj Can you provide documentation of your Answer’s assertion?
– Basil Bourque
Jul 1 '15 at 16:47
@Braj Can you provide documentation of your Answer’s assertion?
– Basil Bourque
Jul 1 '15 at 16:47
@Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
– Rahul Kurup
Aug 8 '15 at 10:52
@Braj: Are the headers for the 'Heap' & 'pool' in the table supposed to be reverse ?
– Rahul Kurup
Aug 8 '15 at 10:52
Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
– user207421
Feb 7 '16 at 9:31
Not correct. The constant pool is created at compile time, not at execution time. Don't use quote formatting for text that isn't quoted.
– user207421
Feb 7 '16 at 9:31
|
show 2 more comments
One creates a String in the String Constant Pool
String s = "text";
the other one creates a string in the constant pool ("text"
) and another string in normal heap space (s
). Both strings will have the same value, that of "text".
String s = new String("text");
s
is then lost (eligible for GC) if later unused.
String literals on the other hand are reused. If you use "text"
in multiple places of your class it will in fact be one and only one String (i.e. multiple references to the same string in the pool).
Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
– user207421
Jun 16 '10 at 10:38
@EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
– user159088
Jun 16 '10 at 10:43
add a comment |
One creates a String in the String Constant Pool
String s = "text";
the other one creates a string in the constant pool ("text"
) and another string in normal heap space (s
). Both strings will have the same value, that of "text".
String s = new String("text");
s
is then lost (eligible for GC) if later unused.
String literals on the other hand are reused. If you use "text"
in multiple places of your class it will in fact be one and only one String (i.e. multiple references to the same string in the pool).
Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
– user207421
Jun 16 '10 at 10:38
@EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
– user159088
Jun 16 '10 at 10:43
add a comment |
One creates a String in the String Constant Pool
String s = "text";
the other one creates a string in the constant pool ("text"
) and another string in normal heap space (s
). Both strings will have the same value, that of "text".
String s = new String("text");
s
is then lost (eligible for GC) if later unused.
String literals on the other hand are reused. If you use "text"
in multiple places of your class it will in fact be one and only one String (i.e. multiple references to the same string in the pool).
One creates a String in the String Constant Pool
String s = "text";
the other one creates a string in the constant pool ("text"
) and another string in normal heap space (s
). Both strings will have the same value, that of "text".
String s = new String("text");
s
is then lost (eligible for GC) if later unused.
String literals on the other hand are reused. If you use "text"
in multiple places of your class it will in fact be one and only one String (i.e. multiple references to the same string in the pool).
edited Jun 16 '10 at 11:57
answered Jun 16 '10 at 10:32
user159088
Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
– user207421
Jun 16 '10 at 10:38
@EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
– user159088
Jun 16 '10 at 10:43
add a comment |
Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
– user207421
Jun 16 '10 at 10:38
@EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
– user159088
Jun 16 '10 at 10:43
Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
– user207421
Jun 16 '10 at 10:38
Strings in the constant pool are never lost. Did you mean to say 's' is lost if later unused?
– user207421
Jun 16 '10 at 10:38
@EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
– user159088
Jun 16 '10 at 10:43
@EJP: yes, I did mean "s". Thanks for noticing. I will correct the question.
– user159088
Jun 16 '10 at 10:43
add a comment |
JLS
The concept is called "interning" by the JLS.
Relevant passage from JLS 7 3.10.5:
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.
Example 3.10.5-1. String Literals
The program consisting of the compilation unit (§7.3):
package testPackage;
class Test {
public static void main(String args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
and the compilation unit:
package other;
public class Other { public static String hello = "Hello"; }
produces the output:
true true true true false true
JVMS
JVMS 7 5.1 says:
A string literal is a reference to an instance of class String, and is derived from a CONSTANT_String_info structure (§4.4.3) in the binary representation of a class or interface. The CONSTANT_String_info structure gives the sequence of Unicode code points constituting the string literal.
The Java programming language requires that identical string literals (that is, literals that contain the same sequence of code points) must refer to the same instance of class String (JLS §3.10.5). In addition, if the method String.intern is called on any string, the result is a reference to the same class instance that would be returned if that string appeared as a literal. Thus, the following expression must have the value true:
("a" + "b" + "c").intern() == "abc"
To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.
If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String.
Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.
Bytecode
It is also instructive to look at the bytecode implementation on OpenJDK 7.
If we decompile:
public class StringPool {
public static void main(String args) {
String a = "abc";
String b = "abc";
String c = new String("abc");
System.out.println(a);
System.out.println(b);
System.out.println(a == c);
}
}
we have on the constant pool:
#2 = String #32 // abc
[...]
#32 = Utf8 abc
and main
:
0: ldc #2 // String abc
2: astore_1
3: ldc #2 // String abc
5: astore_2
6: new #3 // class java/lang/String
9: dup
10: ldc #2 // String abc
12: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
15: astore_3
16: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_2
27: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
30: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
33: aload_1
34: aload_3
35: if_acmpne 42
38: iconst_1
39: goto 43
42: iconst_0
43: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
Note how:
0
and3
: the sameldc #2
constant is loaded (the literals)
12
: a new string instance is created (with#2
as argument)
35
:a
andc
are compared as regular objects withif_acmpne
The representation of constant strings is quite magic on the bytecode:
- it has a dedicated CONSTANT_String_info structure, unlike regular objects (e.g.
new String
) - the struct points to a CONSTANT_Utf8_info Structure that contains the data. That is the only necessary data to represent the string.
and the JVMS quote above seems to say that whenever the Utf8 pointed to is the same, then identical instances are loaded by ldc
.
I have done similar tests for fields, and:
static final String s = "abc"
points to the constant table through the ConstantValue Attribute
- non-final fields don't have that attribute, but can still be initialized with
ldc
Conclusion: there is direct bytecode support for the string pool, and the memory representation is efficient.
Bonus: compare that to the Integer pool, which does not have direct bytecode support (i.e. no CONSTANT_String_info
analogue).
add a comment |
JLS
The concept is called "interning" by the JLS.
Relevant passage from JLS 7 3.10.5:
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.
Example 3.10.5-1. String Literals
The program consisting of the compilation unit (§7.3):
package testPackage;
class Test {
public static void main(String args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
and the compilation unit:
package other;
public class Other { public static String hello = "Hello"; }
produces the output:
true true true true false true
JVMS
JVMS 7 5.1 says:
A string literal is a reference to an instance of class String, and is derived from a CONSTANT_String_info structure (§4.4.3) in the binary representation of a class or interface. The CONSTANT_String_info structure gives the sequence of Unicode code points constituting the string literal.
The Java programming language requires that identical string literals (that is, literals that contain the same sequence of code points) must refer to the same instance of class String (JLS §3.10.5). In addition, if the method String.intern is called on any string, the result is a reference to the same class instance that would be returned if that string appeared as a literal. Thus, the following expression must have the value true:
("a" + "b" + "c").intern() == "abc"
To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.
If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String.
Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.
Bytecode
It is also instructive to look at the bytecode implementation on OpenJDK 7.
If we decompile:
public class StringPool {
public static void main(String args) {
String a = "abc";
String b = "abc";
String c = new String("abc");
System.out.println(a);
System.out.println(b);
System.out.println(a == c);
}
}
we have on the constant pool:
#2 = String #32 // abc
[...]
#32 = Utf8 abc
and main
:
0: ldc #2 // String abc
2: astore_1
3: ldc #2 // String abc
5: astore_2
6: new #3 // class java/lang/String
9: dup
10: ldc #2 // String abc
12: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
15: astore_3
16: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_2
27: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
30: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
33: aload_1
34: aload_3
35: if_acmpne 42
38: iconst_1
39: goto 43
42: iconst_0
43: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
Note how:
0
and3
: the sameldc #2
constant is loaded (the literals)
12
: a new string instance is created (with#2
as argument)
35
:a
andc
are compared as regular objects withif_acmpne
The representation of constant strings is quite magic on the bytecode:
- it has a dedicated CONSTANT_String_info structure, unlike regular objects (e.g.
new String
) - the struct points to a CONSTANT_Utf8_info Structure that contains the data. That is the only necessary data to represent the string.
and the JVMS quote above seems to say that whenever the Utf8 pointed to is the same, then identical instances are loaded by ldc
.
I have done similar tests for fields, and:
static final String s = "abc"
points to the constant table through the ConstantValue Attribute
- non-final fields don't have that attribute, but can still be initialized with
ldc
Conclusion: there is direct bytecode support for the string pool, and the memory representation is efficient.
Bonus: compare that to the Integer pool, which does not have direct bytecode support (i.e. no CONSTANT_String_info
analogue).
add a comment |
JLS
The concept is called "interning" by the JLS.
Relevant passage from JLS 7 3.10.5:
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.
Example 3.10.5-1. String Literals
The program consisting of the compilation unit (§7.3):
package testPackage;
class Test {
public static void main(String args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
and the compilation unit:
package other;
public class Other { public static String hello = "Hello"; }
produces the output:
true true true true false true
JVMS
JVMS 7 5.1 says:
A string literal is a reference to an instance of class String, and is derived from a CONSTANT_String_info structure (§4.4.3) in the binary representation of a class or interface. The CONSTANT_String_info structure gives the sequence of Unicode code points constituting the string literal.
The Java programming language requires that identical string literals (that is, literals that contain the same sequence of code points) must refer to the same instance of class String (JLS §3.10.5). In addition, if the method String.intern is called on any string, the result is a reference to the same class instance that would be returned if that string appeared as a literal. Thus, the following expression must have the value true:
("a" + "b" + "c").intern() == "abc"
To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.
If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String.
Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.
Bytecode
It is also instructive to look at the bytecode implementation on OpenJDK 7.
If we decompile:
public class StringPool {
public static void main(String args) {
String a = "abc";
String b = "abc";
String c = new String("abc");
System.out.println(a);
System.out.println(b);
System.out.println(a == c);
}
}
we have on the constant pool:
#2 = String #32 // abc
[...]
#32 = Utf8 abc
and main
:
0: ldc #2 // String abc
2: astore_1
3: ldc #2 // String abc
5: astore_2
6: new #3 // class java/lang/String
9: dup
10: ldc #2 // String abc
12: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
15: astore_3
16: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_2
27: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
30: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
33: aload_1
34: aload_3
35: if_acmpne 42
38: iconst_1
39: goto 43
42: iconst_0
43: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
Note how:
0
and3
: the sameldc #2
constant is loaded (the literals)
12
: a new string instance is created (with#2
as argument)
35
:a
andc
are compared as regular objects withif_acmpne
The representation of constant strings is quite magic on the bytecode:
- it has a dedicated CONSTANT_String_info structure, unlike regular objects (e.g.
new String
) - the struct points to a CONSTANT_Utf8_info Structure that contains the data. That is the only necessary data to represent the string.
and the JVMS quote above seems to say that whenever the Utf8 pointed to is the same, then identical instances are loaded by ldc
.
I have done similar tests for fields, and:
static final String s = "abc"
points to the constant table through the ConstantValue Attribute
- non-final fields don't have that attribute, but can still be initialized with
ldc
Conclusion: there is direct bytecode support for the string pool, and the memory representation is efficient.
Bonus: compare that to the Integer pool, which does not have direct bytecode support (i.e. no CONSTANT_String_info
analogue).
JLS
The concept is called "interning" by the JLS.
Relevant passage from JLS 7 3.10.5:
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.
Example 3.10.5-1. String Literals
The program consisting of the compilation unit (§7.3):
package testPackage;
class Test {
public static void main(String args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");
System.out.print((Other.hello == hello) + " ");
System.out.print((other.Other.hello == hello) + " ");
System.out.print((hello == ("Hel"+"lo")) + " ");
System.out.print((hello == ("Hel"+lo)) + " ");
System.out.println(hello == ("Hel"+lo).intern());
}
}
class Other { static String hello = "Hello"; }
and the compilation unit:
package other;
public class Other { public static String hello = "Hello"; }
produces the output:
true true true true false true
JVMS
JVMS 7 5.1 says:
A string literal is a reference to an instance of class String, and is derived from a CONSTANT_String_info structure (§4.4.3) in the binary representation of a class or interface. The CONSTANT_String_info structure gives the sequence of Unicode code points constituting the string literal.
The Java programming language requires that identical string literals (that is, literals that contain the same sequence of code points) must refer to the same instance of class String (JLS §3.10.5). In addition, if the method String.intern is called on any string, the result is a reference to the same class instance that would be returned if that string appeared as a literal. Thus, the following expression must have the value true:
("a" + "b" + "c").intern() == "abc"
To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.
If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String.
Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.
Bytecode
It is also instructive to look at the bytecode implementation on OpenJDK 7.
If we decompile:
public class StringPool {
public static void main(String args) {
String a = "abc";
String b = "abc";
String c = new String("abc");
System.out.println(a);
System.out.println(b);
System.out.println(a == c);
}
}
we have on the constant pool:
#2 = String #32 // abc
[...]
#32 = Utf8 abc
and main
:
0: ldc #2 // String abc
2: astore_1
3: ldc #2 // String abc
5: astore_2
6: new #3 // class java/lang/String
9: dup
10: ldc #2 // String abc
12: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V
15: astore_3
16: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
26: aload_2
27: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
30: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
33: aload_1
34: aload_3
35: if_acmpne 42
38: iconst_1
39: goto 43
42: iconst_0
43: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
Note how:
0
and3
: the sameldc #2
constant is loaded (the literals)
12
: a new string instance is created (with#2
as argument)
35
:a
andc
are compared as regular objects withif_acmpne
The representation of constant strings is quite magic on the bytecode:
- it has a dedicated CONSTANT_String_info structure, unlike regular objects (e.g.
new String
) - the struct points to a CONSTANT_Utf8_info Structure that contains the data. That is the only necessary data to represent the string.
and the JVMS quote above seems to say that whenever the Utf8 pointed to is the same, then identical instances are loaded by ldc
.
I have done similar tests for fields, and:
static final String s = "abc"
points to the constant table through the ConstantValue Attribute
- non-final fields don't have that attribute, but can still be initialized with
ldc
Conclusion: there is direct bytecode support for the string pool, and the memory representation is efficient.
Bonus: compare that to the Integer pool, which does not have direct bytecode support (i.e. no CONSTANT_String_info
analogue).
edited Jul 28 '17 at 16:59
answered Apr 15 '17 at 7:18
Ciro Santilli 新疆改造中心 六四事件 法轮功
134k30524451
134k30524451
add a comment |
add a comment |
Think of "bla"
being a magic factory like Strings.createString("bla")
(pseudo). The factory holds a pool of all strings yet created this way.
If it gets invoked, it checks if there is already string in the pool with this value. If true, it returns this string object, hence to strings obtained this way are indeed the same object.
If not, it creates a new string object internally, saves it in the pool and then returns it. Thus, when the same string value is queried the next time, it returns the same instance.
Manually creating new String("")
overrides this behaviour by bypassing the string literal pool. So equality should always be checked using equals()
which compares the character sequence instead of the object reference equality.
The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
– user207421
Feb 7 '16 at 9:20
add a comment |
Think of "bla"
being a magic factory like Strings.createString("bla")
(pseudo). The factory holds a pool of all strings yet created this way.
If it gets invoked, it checks if there is already string in the pool with this value. If true, it returns this string object, hence to strings obtained this way are indeed the same object.
If not, it creates a new string object internally, saves it in the pool and then returns it. Thus, when the same string value is queried the next time, it returns the same instance.
Manually creating new String("")
overrides this behaviour by bypassing the string literal pool. So equality should always be checked using equals()
which compares the character sequence instead of the object reference equality.
The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
– user207421
Feb 7 '16 at 9:20
add a comment |
Think of "bla"
being a magic factory like Strings.createString("bla")
(pseudo). The factory holds a pool of all strings yet created this way.
If it gets invoked, it checks if there is already string in the pool with this value. If true, it returns this string object, hence to strings obtained this way are indeed the same object.
If not, it creates a new string object internally, saves it in the pool and then returns it. Thus, when the same string value is queried the next time, it returns the same instance.
Manually creating new String("")
overrides this behaviour by bypassing the string literal pool. So equality should always be checked using equals()
which compares the character sequence instead of the object reference equality.
Think of "bla"
being a magic factory like Strings.createString("bla")
(pseudo). The factory holds a pool of all strings yet created this way.
If it gets invoked, it checks if there is already string in the pool with this value. If true, it returns this string object, hence to strings obtained this way are indeed the same object.
If not, it creates a new string object internally, saves it in the pool and then returns it. Thus, when the same string value is queried the next time, it returns the same instance.
Manually creating new String("")
overrides this behaviour by bypassing the string literal pool. So equality should always be checked using equals()
which compares the character sequence instead of the object reference equality.
answered Jun 16 '10 at 10:46
b_erb
15.9k84461
15.9k84461
The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
– user207421
Feb 7 '16 at 9:20
add a comment |
The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
– user207421
Feb 7 '16 at 9:20
The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
– user207421
Feb 7 '16 at 9:20
The 'magic factory' you refer to is nothing more or less than the Java compiler. It is a mistake to write of this process as though it occurred at runtime.
– user207421
Feb 7 '16 at 9:20
add a comment |
One simple way to understand the difference is below:-
String s ="abc";
String s1= "abc";
String s2=new String("abc");
if(s==s1){
System.out.println("s==s1 is true");
}else{
System.out.println("s==s1 is false");
}
if(s==s2){
System.out.println("s==s2 is true");
}else{
System.out.println("s==s2 is false");
}
output is
s==s1 is true
s==s2 is false
Thus new String() will always create a new instance.
add a comment |
One simple way to understand the difference is below:-
String s ="abc";
String s1= "abc";
String s2=new String("abc");
if(s==s1){
System.out.println("s==s1 is true");
}else{
System.out.println("s==s1 is false");
}
if(s==s2){
System.out.println("s==s2 is true");
}else{
System.out.println("s==s2 is false");
}
output is
s==s1 is true
s==s2 is false
Thus new String() will always create a new instance.
add a comment |
One simple way to understand the difference is below:-
String s ="abc";
String s1= "abc";
String s2=new String("abc");
if(s==s1){
System.out.println("s==s1 is true");
}else{
System.out.println("s==s1 is false");
}
if(s==s2){
System.out.println("s==s2 is true");
}else{
System.out.println("s==s2 is false");
}
output is
s==s1 is true
s==s2 is false
Thus new String() will always create a new instance.
One simple way to understand the difference is below:-
String s ="abc";
String s1= "abc";
String s2=new String("abc");
if(s==s1){
System.out.println("s==s1 is true");
}else{
System.out.println("s==s1 is false");
}
if(s==s2){
System.out.println("s==s2 is true");
}else{
System.out.println("s==s2 is false");
}
output is
s==s1 is true
s==s2 is false
Thus new String() will always create a new instance.
answered Jun 16 '10 at 11:19
Shashank T
479159
479159
add a comment |
add a comment |
@Braj : i think u have mentioned the other way around. Please correct me if i am wrong
Object creation line by line:
String str1 = new String("java5")
Pool- "java5" (1 Object)
Heap - str1 => "java5" (1 Object)
String str2 = "java5"
pool- str2 => "java5" (1 Object)
heap - str1 => "java5" (1 Object)
String str3 = new String(str2)
pool- str2 => "java5" (1 Object)
heap- str1 => "java5", str3 => "java5" (2 Objects)
String str4 = "java5"
pool - str2 => str4 => "java5" (1 Object)
heap - str1 => "java5", str3 => "java5" (2 Objects)
str1
is not involved in the value ofstr2
orstr3
orstr4
in any way.
– user207421
Feb 7 '16 at 9:24
add a comment |
@Braj : i think u have mentioned the other way around. Please correct me if i am wrong
Object creation line by line:
String str1 = new String("java5")
Pool- "java5" (1 Object)
Heap - str1 => "java5" (1 Object)
String str2 = "java5"
pool- str2 => "java5" (1 Object)
heap - str1 => "java5" (1 Object)
String str3 = new String(str2)
pool- str2 => "java5" (1 Object)
heap- str1 => "java5", str3 => "java5" (2 Objects)
String str4 = "java5"
pool - str2 => str4 => "java5" (1 Object)
heap - str1 => "java5", str3 => "java5" (2 Objects)
str1
is not involved in the value ofstr2
orstr3
orstr4
in any way.
– user207421
Feb 7 '16 at 9:24
add a comment |
@Braj : i think u have mentioned the other way around. Please correct me if i am wrong
Object creation line by line:
String str1 = new String("java5")
Pool- "java5" (1 Object)
Heap - str1 => "java5" (1 Object)
String str2 = "java5"
pool- str2 => "java5" (1 Object)
heap - str1 => "java5" (1 Object)
String str3 = new String(str2)
pool- str2 => "java5" (1 Object)
heap- str1 => "java5", str3 => "java5" (2 Objects)
String str4 = "java5"
pool - str2 => str4 => "java5" (1 Object)
heap - str1 => "java5", str3 => "java5" (2 Objects)
@Braj : i think u have mentioned the other way around. Please correct me if i am wrong
Object creation line by line:
String str1 = new String("java5")
Pool- "java5" (1 Object)
Heap - str1 => "java5" (1 Object)
String str2 = "java5"
pool- str2 => "java5" (1 Object)
heap - str1 => "java5" (1 Object)
String str3 = new String(str2)
pool- str2 => "java5" (1 Object)
heap- str1 => "java5", str3 => "java5" (2 Objects)
String str4 = "java5"
pool - str2 => str4 => "java5" (1 Object)
heap - str1 => "java5", str3 => "java5" (2 Objects)
answered Jul 7 '15 at 2:32
SDC
4610
4610
str1
is not involved in the value ofstr2
orstr3
orstr4
in any way.
– user207421
Feb 7 '16 at 9:24
add a comment |
str1
is not involved in the value ofstr2
orstr3
orstr4
in any way.
– user207421
Feb 7 '16 at 9:24
str1
is not involved in the value of str2
or str3
or str4
in any way.– user207421
Feb 7 '16 at 9:24
str1
is not involved in the value of str2
or str3
or str4
in any way.– user207421
Feb 7 '16 at 9:24
add a comment |
Although it looks the same from a programmers point of view, it has big performance impact. You would want to use the first form almost always.
add a comment |
Although it looks the same from a programmers point of view, it has big performance impact. You would want to use the first form almost always.
add a comment |
Although it looks the same from a programmers point of view, it has big performance impact. You would want to use the first form almost always.
Although it looks the same from a programmers point of view, it has big performance impact. You would want to use the first form almost always.
answered Jun 17 '10 at 4:38
fastcodejava
23.8k19109160
23.8k19109160
add a comment |
add a comment |
String str = new String("hello")
It will check whether String constant pool already contains String "hello"?
If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.
An object will be created in a heap memory area and str
reference points to object created in heap memory location.
if you want str
reference to point object containing in String constant pool then one has to explicitly call str.intern();
String str = "world";
It will check whether String constant pool already contains String "hello"?
If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.
In both the above case, str
reference points to String "world"
present in Constant pool.
'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
– user207421
Feb 7 '16 at 9:28
Can you please explain what is wrong in this post clearly?
– Jayesh
Feb 7 '16 at 9:46
What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
– user207421
Oct 22 '16 at 7:22
@EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
– Jayesh
Oct 22 '16 at 7:43
You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
– user207421
Aug 23 '17 at 4:02
add a comment |
String str = new String("hello")
It will check whether String constant pool already contains String "hello"?
If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.
An object will be created in a heap memory area and str
reference points to object created in heap memory location.
if you want str
reference to point object containing in String constant pool then one has to explicitly call str.intern();
String str = "world";
It will check whether String constant pool already contains String "hello"?
If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.
In both the above case, str
reference points to String "world"
present in Constant pool.
'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
– user207421
Feb 7 '16 at 9:28
Can you please explain what is wrong in this post clearly?
– Jayesh
Feb 7 '16 at 9:46
What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
– user207421
Oct 22 '16 at 7:22
@EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
– Jayesh
Oct 22 '16 at 7:43
You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
– user207421
Aug 23 '17 at 4:02
add a comment |
String str = new String("hello")
It will check whether String constant pool already contains String "hello"?
If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.
An object will be created in a heap memory area and str
reference points to object created in heap memory location.
if you want str
reference to point object containing in String constant pool then one has to explicitly call str.intern();
String str = "world";
It will check whether String constant pool already contains String "hello"?
If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.
In both the above case, str
reference points to String "world"
present in Constant pool.
String str = new String("hello")
It will check whether String constant pool already contains String "hello"?
If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.
An object will be created in a heap memory area and str
reference points to object created in heap memory location.
if you want str
reference to point object containing in String constant pool then one has to explicitly call str.intern();
String str = "world";
It will check whether String constant pool already contains String "hello"?
If present then it will not add an entry in String constant pool. If not present then it will add an entry in String constant pool.
In both the above case, str
reference points to String "world"
present in Constant pool.
answered Sep 15 '15 at 10:24
Jayesh
3,14573767
3,14573767
'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
– user207421
Feb 7 '16 at 9:28
Can you please explain what is wrong in this post clearly?
– Jayesh
Feb 7 '16 at 9:46
What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
– user207421
Oct 22 '16 at 7:22
@EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
– Jayesh
Oct 22 '16 at 7:43
You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
– user207421
Aug 23 '17 at 4:02
add a comment |
'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
– user207421
Feb 7 '16 at 9:28
Can you please explain what is wrong in this post clearly?
– Jayesh
Feb 7 '16 at 9:46
What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
– user207421
Oct 22 '16 at 7:22
@EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
– Jayesh
Oct 22 '16 at 7:43
You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
– user207421
Aug 23 '17 at 4:02
'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
– user207421
Feb 7 '16 at 9:28
'It' being the Java compiler. The string literal creates a unique entry in the constant pool, at compile time. It's a mistake to deacribe this process as though it happens at runtime..
– user207421
Feb 7 '16 at 9:28
Can you please explain what is wrong in this post clearly?
– Jayesh
Feb 7 '16 at 9:46
Can you please explain what is wrong in this post clearly?
– Jayesh
Feb 7 '16 at 9:46
What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
– user207421
Oct 22 '16 at 7:22
What is wrong in this post is that the string literal is pooled at complle time, as I already said. Not when executing the code, as in your answer.
– user207421
Oct 22 '16 at 7:22
@EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
– Jayesh
Oct 22 '16 at 7:43
@EJP I appreciate your response. Can you please point out the exact line which is wrong in answer. I see all answers above are same as what i wrote. Please help, I want to correct my understanding. Thanks.
– Jayesh
Oct 22 '16 at 7:43
You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
– user207421
Aug 23 '17 at 4:02
You have written about the entire process as though it all takes place when the line of code is executed, which, as I have repeatedly told you, is not the case. You can't reduce all that to a single 'exact line' being wrong in your answer.
– user207421
Aug 23 '17 at 4:02
add a comment |
protected by ΦXocę 웃 Пepeúpa ツ Sep 8 '17 at 5:49
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
Related topic: JEP 192: String Deduplication in G1.
– Basil Bourque
Jun 7 at 22:49