If String is immutable, if String constant pool having only one copy of a particular value how the following...
This question already has an answer here:
concatenation of string constants in java [duplicate]
2 answers
String s1 = "A"+"B";
String s2 = "AB";
System.out.println(s1 == s2); // true
String s1 and s2 should refer to String value "AB" in String constant pool. So one value "AB" one reference, reference comparison giving is true. (this is acceptable according to the theory I am aware of)
String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1 == str2); // false
String str1 and str2 both should refer to String "C D E" in String constant pool (two identical values cannot be in String pool ). Then why the reference comparison of str1 and str2 return false?
What I am missing here?
Thanks
java string
marked as duplicate by GhostCat
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 14 '18 at 11:48
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
|
show 6 more comments
This question already has an answer here:
concatenation of string constants in java [duplicate]
2 answers
String s1 = "A"+"B";
String s2 = "AB";
System.out.println(s1 == s2); // true
String s1 and s2 should refer to String value "AB" in String constant pool. So one value "AB" one reference, reference comparison giving is true. (this is acceptable according to the theory I am aware of)
String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1 == str2); // false
String str1 and str2 both should refer to String "C D E" in String constant pool (two identical values cannot be in String pool ). Then why the reference comparison of str1 and str2 return false?
What I am missing here?
Thanks
java string
marked as duplicate by GhostCat
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 14 '18 at 11:48
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
@AlexSalauyou st1 += " E". so st1, shouldn't it hold the reference to "C D E" in string constant pool?
– shanika yrs
Nov 14 '18 at 11:05
@AlexSalauyou pretty surest1 += " E"
is just the short form ofst1 = st1 + " E"
and both will produce the same bytecode and in fact change/reassignst1
– OH GOD SPIDERS
Nov 14 '18 at 11:06
@OHGODSPIDERS shame on me ) thanks
– Alex Salauyou
Nov 14 '18 at 11:07
6
The reason is that in first case "A" + "B" is evaluated to constant "AB" in compile time, thus result is taken from the pool on instance initialization. In second case, you perform operation in code flow. There is no guarantee that equivalent Strings are same object until you adjust them callingString#intern
– Alex Salauyou
Nov 14 '18 at 11:08
1
docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5
– Alex Salauyou
Nov 14 '18 at 11:12
|
show 6 more comments
This question already has an answer here:
concatenation of string constants in java [duplicate]
2 answers
String s1 = "A"+"B";
String s2 = "AB";
System.out.println(s1 == s2); // true
String s1 and s2 should refer to String value "AB" in String constant pool. So one value "AB" one reference, reference comparison giving is true. (this is acceptable according to the theory I am aware of)
String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1 == str2); // false
String str1 and str2 both should refer to String "C D E" in String constant pool (two identical values cannot be in String pool ). Then why the reference comparison of str1 and str2 return false?
What I am missing here?
Thanks
java string
This question already has an answer here:
concatenation of string constants in java [duplicate]
2 answers
String s1 = "A"+"B";
String s2 = "AB";
System.out.println(s1 == s2); // true
String s1 and s2 should refer to String value "AB" in String constant pool. So one value "AB" one reference, reference comparison giving is true. (this is acceptable according to the theory I am aware of)
String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1 == str2); // false
String str1 and str2 both should refer to String "C D E" in String constant pool (two identical values cannot be in String pool ). Then why the reference comparison of str1 and str2 return false?
What I am missing here?
Thanks
This question already has an answer here:
concatenation of string constants in java [duplicate]
2 answers
java string
java string
edited Nov 14 '18 at 11:30
Morteza Jalambadani
7361921
7361921
asked Nov 14 '18 at 11:01
shanika yrsshanika yrs
939
939
marked as duplicate by GhostCat
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 14 '18 at 11:48
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by GhostCat
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 14 '18 at 11:48
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
@AlexSalauyou st1 += " E". so st1, shouldn't it hold the reference to "C D E" in string constant pool?
– shanika yrs
Nov 14 '18 at 11:05
@AlexSalauyou pretty surest1 += " E"
is just the short form ofst1 = st1 + " E"
and both will produce the same bytecode and in fact change/reassignst1
– OH GOD SPIDERS
Nov 14 '18 at 11:06
@OHGODSPIDERS shame on me ) thanks
– Alex Salauyou
Nov 14 '18 at 11:07
6
The reason is that in first case "A" + "B" is evaluated to constant "AB" in compile time, thus result is taken from the pool on instance initialization. In second case, you perform operation in code flow. There is no guarantee that equivalent Strings are same object until you adjust them callingString#intern
– Alex Salauyou
Nov 14 '18 at 11:08
1
docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5
– Alex Salauyou
Nov 14 '18 at 11:12
|
show 6 more comments
@AlexSalauyou st1 += " E". so st1, shouldn't it hold the reference to "C D E" in string constant pool?
– shanika yrs
Nov 14 '18 at 11:05
@AlexSalauyou pretty surest1 += " E"
is just the short form ofst1 = st1 + " E"
and both will produce the same bytecode and in fact change/reassignst1
– OH GOD SPIDERS
Nov 14 '18 at 11:06
@OHGODSPIDERS shame on me ) thanks
– Alex Salauyou
Nov 14 '18 at 11:07
6
The reason is that in first case "A" + "B" is evaluated to constant "AB" in compile time, thus result is taken from the pool on instance initialization. In second case, you perform operation in code flow. There is no guarantee that equivalent Strings are same object until you adjust them callingString#intern
– Alex Salauyou
Nov 14 '18 at 11:08
1
docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5
– Alex Salauyou
Nov 14 '18 at 11:12
@AlexSalauyou st1 += " E". so st1, shouldn't it hold the reference to "C D E" in string constant pool?
– shanika yrs
Nov 14 '18 at 11:05
@AlexSalauyou st1 += " E". so st1, shouldn't it hold the reference to "C D E" in string constant pool?
– shanika yrs
Nov 14 '18 at 11:05
@AlexSalauyou pretty sure
st1 += " E"
is just the short form of st1 = st1 + " E"
and both will produce the same bytecode and in fact change/reassign st1
– OH GOD SPIDERS
Nov 14 '18 at 11:06
@AlexSalauyou pretty sure
st1 += " E"
is just the short form of st1 = st1 + " E"
and both will produce the same bytecode and in fact change/reassign st1
– OH GOD SPIDERS
Nov 14 '18 at 11:06
@OHGODSPIDERS shame on me ) thanks
– Alex Salauyou
Nov 14 '18 at 11:07
@OHGODSPIDERS shame on me ) thanks
– Alex Salauyou
Nov 14 '18 at 11:07
6
6
The reason is that in first case "A" + "B" is evaluated to constant "AB" in compile time, thus result is taken from the pool on instance initialization. In second case, you perform operation in code flow. There is no guarantee that equivalent Strings are same object until you adjust them calling
String#intern
– Alex Salauyou
Nov 14 '18 at 11:08
The reason is that in first case "A" + "B" is evaluated to constant "AB" in compile time, thus result is taken from the pool on instance initialization. In second case, you perform operation in code flow. There is no guarantee that equivalent Strings are same object until you adjust them calling
String#intern
– Alex Salauyou
Nov 14 '18 at 11:08
1
1
docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5
– Alex Salauyou
Nov 14 '18 at 11:12
docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5
– Alex Salauyou
Nov 14 '18 at 11:12
|
show 6 more comments
4 Answers
4
active
oldest
votes
The answer is very simple.
When you type String st1 += " E"
or String st1 = st1 + " E"
JVM transforms it to the StringBuilder
syntax like String st1 = new StringBuilder(st1).append(" E").toString()
.
When you look at StringBuilder.toString()
:
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
... you see new String()
, it creates new string not using constants from String Pool.
Finally, if you replace st1 += " E"
to s1 = (s1 + " E").intern()
, you get true
as results.
P.S.
If I remember correctly, this is valid from JVM 6 or so. That's why now you can use string concatenation str = str1 + str2
(internally this is str = new StringBuilder(str1).append(str2).toString()
). But it is not true, when you use it inside loop:
String str = "A";
for(int i = 1; i <= 3; i++)
str += i;
JVM cannot optimize it to use StringBuilder
and does old-style concatenation with generating multiple temporary strings, which is very slowly.
add a comment |
In addition to Alex Salauyou and oleg.cherednik answers:
In bytecode below you can see, that string s1 was evaluated on compile time as Alex Salauyou told, but the second string was constructed with StringBuilder as oleg.cherednik explained.
Code:
0: ldc #2 // String AB <- s1 evaluated on compile time there
2: astore_1
3: ldc #2 // String AB
5: astore_2
6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
9: aload_1
10: aload_2
11: if_acmpne 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
22: ldc #5 // String C D
24: astore_3
25: new #6 // class java/lang/StringBuilder
28: dup
29: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
32: aload_3
33: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
36: ldc #9 // String E
38: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
41: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
44: astore_3
45: ldc #11 // String C D E
47: astore 4
49: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
52: aload_3
53: aload 4
55: if_acmpne 62
58: iconst_1
59: goto 63
62: iconst_0
63: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
66: return
add a comment |
The rule you mentioned regards string literals, i.e. pieces of code written in double quotes, like "AB"
. Result of operation, which may be evaluated on compile time ("constant expression"), is immediately replaced by resulting literal:
String st1 = "A" + "B";
is the same as writing:
String st1 = "AB";
And equal literals are always evaluated to same String
object, as told in specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-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"
In your question, you assume that constant pool cannot hold two different instances of the same value, that is right, but that does not imply that every String instance resides in constant pool. In fact, there is no possibility to guaranteely make equal strings created on runtime be the same object, for example:
String st1 = "AB";
String st2 = new String(st1);
String st3 = new String(st1);
will result in three different String instances: first as literal evaluation result, taken from constant pool, others as newly constructed objects (though new
always creates a new object!). ==
on them will fail unless you adjust them using String#intern
:
st1 == st2.intern(); // true
add a comment |
st1 + " E"
this line of code will reassign
String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1.hashCode() == str2.hashCode()); //True
fetch the internal address that same
thank u
String#hashCode
is calculated upon its value, not "internal address"
– Alex Salauyou
Nov 14 '18 at 12:18
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
The answer is very simple.
When you type String st1 += " E"
or String st1 = st1 + " E"
JVM transforms it to the StringBuilder
syntax like String st1 = new StringBuilder(st1).append(" E").toString()
.
When you look at StringBuilder.toString()
:
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
... you see new String()
, it creates new string not using constants from String Pool.
Finally, if you replace st1 += " E"
to s1 = (s1 + " E").intern()
, you get true
as results.
P.S.
If I remember correctly, this is valid from JVM 6 or so. That's why now you can use string concatenation str = str1 + str2
(internally this is str = new StringBuilder(str1).append(str2).toString()
). But it is not true, when you use it inside loop:
String str = "A";
for(int i = 1; i <= 3; i++)
str += i;
JVM cannot optimize it to use StringBuilder
and does old-style concatenation with generating multiple temporary strings, which is very slowly.
add a comment |
The answer is very simple.
When you type String st1 += " E"
or String st1 = st1 + " E"
JVM transforms it to the StringBuilder
syntax like String st1 = new StringBuilder(st1).append(" E").toString()
.
When you look at StringBuilder.toString()
:
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
... you see new String()
, it creates new string not using constants from String Pool.
Finally, if you replace st1 += " E"
to s1 = (s1 + " E").intern()
, you get true
as results.
P.S.
If I remember correctly, this is valid from JVM 6 or so. That's why now you can use string concatenation str = str1 + str2
(internally this is str = new StringBuilder(str1).append(str2).toString()
). But it is not true, when you use it inside loop:
String str = "A";
for(int i = 1; i <= 3; i++)
str += i;
JVM cannot optimize it to use StringBuilder
and does old-style concatenation with generating multiple temporary strings, which is very slowly.
add a comment |
The answer is very simple.
When you type String st1 += " E"
or String st1 = st1 + " E"
JVM transforms it to the StringBuilder
syntax like String st1 = new StringBuilder(st1).append(" E").toString()
.
When you look at StringBuilder.toString()
:
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
... you see new String()
, it creates new string not using constants from String Pool.
Finally, if you replace st1 += " E"
to s1 = (s1 + " E").intern()
, you get true
as results.
P.S.
If I remember correctly, this is valid from JVM 6 or so. That's why now you can use string concatenation str = str1 + str2
(internally this is str = new StringBuilder(str1).append(str2).toString()
). But it is not true, when you use it inside loop:
String str = "A";
for(int i = 1; i <= 3; i++)
str += i;
JVM cannot optimize it to use StringBuilder
and does old-style concatenation with generating multiple temporary strings, which is very slowly.
The answer is very simple.
When you type String st1 += " E"
or String st1 = st1 + " E"
JVM transforms it to the StringBuilder
syntax like String st1 = new StringBuilder(st1).append(" E").toString()
.
When you look at StringBuilder.toString()
:
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
... you see new String()
, it creates new string not using constants from String Pool.
Finally, if you replace st1 += " E"
to s1 = (s1 + " E").intern()
, you get true
as results.
P.S.
If I remember correctly, this is valid from JVM 6 or so. That's why now you can use string concatenation str = str1 + str2
(internally this is str = new StringBuilder(str1).append(str2).toString()
). But it is not true, when you use it inside loop:
String str = "A";
for(int i = 1; i <= 3; i++)
str += i;
JVM cannot optimize it to use StringBuilder
and does old-style concatenation with generating multiple temporary strings, which is very slowly.
edited Nov 14 '18 at 11:39
answered Nov 14 '18 at 11:21
oleg.cherednikoleg.cherednik
6,60221118
6,60221118
add a comment |
add a comment |
In addition to Alex Salauyou and oleg.cherednik answers:
In bytecode below you can see, that string s1 was evaluated on compile time as Alex Salauyou told, but the second string was constructed with StringBuilder as oleg.cherednik explained.
Code:
0: ldc #2 // String AB <- s1 evaluated on compile time there
2: astore_1
3: ldc #2 // String AB
5: astore_2
6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
9: aload_1
10: aload_2
11: if_acmpne 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
22: ldc #5 // String C D
24: astore_3
25: new #6 // class java/lang/StringBuilder
28: dup
29: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
32: aload_3
33: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
36: ldc #9 // String E
38: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
41: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
44: astore_3
45: ldc #11 // String C D E
47: astore 4
49: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
52: aload_3
53: aload 4
55: if_acmpne 62
58: iconst_1
59: goto 63
62: iconst_0
63: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
66: return
add a comment |
In addition to Alex Salauyou and oleg.cherednik answers:
In bytecode below you can see, that string s1 was evaluated on compile time as Alex Salauyou told, but the second string was constructed with StringBuilder as oleg.cherednik explained.
Code:
0: ldc #2 // String AB <- s1 evaluated on compile time there
2: astore_1
3: ldc #2 // String AB
5: astore_2
6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
9: aload_1
10: aload_2
11: if_acmpne 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
22: ldc #5 // String C D
24: astore_3
25: new #6 // class java/lang/StringBuilder
28: dup
29: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
32: aload_3
33: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
36: ldc #9 // String E
38: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
41: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
44: astore_3
45: ldc #11 // String C D E
47: astore 4
49: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
52: aload_3
53: aload 4
55: if_acmpne 62
58: iconst_1
59: goto 63
62: iconst_0
63: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
66: return
add a comment |
In addition to Alex Salauyou and oleg.cherednik answers:
In bytecode below you can see, that string s1 was evaluated on compile time as Alex Salauyou told, but the second string was constructed with StringBuilder as oleg.cherednik explained.
Code:
0: ldc #2 // String AB <- s1 evaluated on compile time there
2: astore_1
3: ldc #2 // String AB
5: astore_2
6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
9: aload_1
10: aload_2
11: if_acmpne 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
22: ldc #5 // String C D
24: astore_3
25: new #6 // class java/lang/StringBuilder
28: dup
29: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
32: aload_3
33: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
36: ldc #9 // String E
38: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
41: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
44: astore_3
45: ldc #11 // String C D E
47: astore 4
49: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
52: aload_3
53: aload 4
55: if_acmpne 62
58: iconst_1
59: goto 63
62: iconst_0
63: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
66: return
In addition to Alex Salauyou and oleg.cherednik answers:
In bytecode below you can see, that string s1 was evaluated on compile time as Alex Salauyou told, but the second string was constructed with StringBuilder as oleg.cherednik explained.
Code:
0: ldc #2 // String AB <- s1 evaluated on compile time there
2: astore_1
3: ldc #2 // String AB
5: astore_2
6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
9: aload_1
10: aload_2
11: if_acmpne 18
14: iconst_1
15: goto 19
18: iconst_0
19: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
22: ldc #5 // String C D
24: astore_3
25: new #6 // class java/lang/StringBuilder
28: dup
29: invokespecial #7 // Method java/lang/StringBuilder."<init>":()V
32: aload_3
33: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
36: ldc #9 // String E
38: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
41: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
44: astore_3
45: ldc #11 // String C D E
47: astore 4
49: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
52: aload_3
53: aload 4
55: if_acmpne 62
58: iconst_1
59: goto 63
62: iconst_0
63: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
66: return
answered Nov 14 '18 at 11:42
Aleksandr SemyannikovAleksandr Semyannikov
591216
591216
add a comment |
add a comment |
The rule you mentioned regards string literals, i.e. pieces of code written in double quotes, like "AB"
. Result of operation, which may be evaluated on compile time ("constant expression"), is immediately replaced by resulting literal:
String st1 = "A" + "B";
is the same as writing:
String st1 = "AB";
And equal literals are always evaluated to same String
object, as told in specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-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"
In your question, you assume that constant pool cannot hold two different instances of the same value, that is right, but that does not imply that every String instance resides in constant pool. In fact, there is no possibility to guaranteely make equal strings created on runtime be the same object, for example:
String st1 = "AB";
String st2 = new String(st1);
String st3 = new String(st1);
will result in three different String instances: first as literal evaluation result, taken from constant pool, others as newly constructed objects (though new
always creates a new object!). ==
on them will fail unless you adjust them using String#intern
:
st1 == st2.intern(); // true
add a comment |
The rule you mentioned regards string literals, i.e. pieces of code written in double quotes, like "AB"
. Result of operation, which may be evaluated on compile time ("constant expression"), is immediately replaced by resulting literal:
String st1 = "A" + "B";
is the same as writing:
String st1 = "AB";
And equal literals are always evaluated to same String
object, as told in specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-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"
In your question, you assume that constant pool cannot hold two different instances of the same value, that is right, but that does not imply that every String instance resides in constant pool. In fact, there is no possibility to guaranteely make equal strings created on runtime be the same object, for example:
String st1 = "AB";
String st2 = new String(st1);
String st3 = new String(st1);
will result in three different String instances: first as literal evaluation result, taken from constant pool, others as newly constructed objects (though new
always creates a new object!). ==
on them will fail unless you adjust them using String#intern
:
st1 == st2.intern(); // true
add a comment |
The rule you mentioned regards string literals, i.e. pieces of code written in double quotes, like "AB"
. Result of operation, which may be evaluated on compile time ("constant expression"), is immediately replaced by resulting literal:
String st1 = "A" + "B";
is the same as writing:
String st1 = "AB";
And equal literals are always evaluated to same String
object, as told in specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-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"
In your question, you assume that constant pool cannot hold two different instances of the same value, that is right, but that does not imply that every String instance resides in constant pool. In fact, there is no possibility to guaranteely make equal strings created on runtime be the same object, for example:
String st1 = "AB";
String st2 = new String(st1);
String st3 = new String(st1);
will result in three different String instances: first as literal evaluation result, taken from constant pool, others as newly constructed objects (though new
always creates a new object!). ==
on them will fail unless you adjust them using String#intern
:
st1 == st2.intern(); // true
The rule you mentioned regards string literals, i.e. pieces of code written in double quotes, like "AB"
. Result of operation, which may be evaluated on compile time ("constant expression"), is immediately replaced by resulting literal:
String st1 = "A" + "B";
is the same as writing:
String st1 = "AB";
And equal literals are always evaluated to same String
object, as told in specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-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"
In your question, you assume that constant pool cannot hold two different instances of the same value, that is right, but that does not imply that every String instance resides in constant pool. In fact, there is no possibility to guaranteely make equal strings created on runtime be the same object, for example:
String st1 = "AB";
String st2 = new String(st1);
String st3 = new String(st1);
will result in three different String instances: first as literal evaluation result, taken from constant pool, others as newly constructed objects (though new
always creates a new object!). ==
on them will fail unless you adjust them using String#intern
:
st1 == st2.intern(); // true
edited Nov 14 '18 at 12:49
answered Nov 14 '18 at 11:27
Alex SalauyouAlex Salauyou
11.1k43359
11.1k43359
add a comment |
add a comment |
st1 + " E"
this line of code will reassign
String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1.hashCode() == str2.hashCode()); //True
fetch the internal address that same
thank u
String#hashCode
is calculated upon its value, not "internal address"
– Alex Salauyou
Nov 14 '18 at 12:18
add a comment |
st1 + " E"
this line of code will reassign
String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1.hashCode() == str2.hashCode()); //True
fetch the internal address that same
thank u
String#hashCode
is calculated upon its value, not "internal address"
– Alex Salauyou
Nov 14 '18 at 12:18
add a comment |
st1 + " E"
this line of code will reassign
String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1.hashCode() == str2.hashCode()); //True
fetch the internal address that same
thank u
st1 + " E"
this line of code will reassign
String st1 = "C D";
st1 += " E";
String str2 = "C D E";
System.out.println(st1.hashCode() == str2.hashCode()); //True
fetch the internal address that same
thank u
answered Nov 14 '18 at 11:47
vishnu.ppvishnu.pp
14
14
String#hashCode
is calculated upon its value, not "internal address"
– Alex Salauyou
Nov 14 '18 at 12:18
add a comment |
String#hashCode
is calculated upon its value, not "internal address"
– Alex Salauyou
Nov 14 '18 at 12:18
String#hashCode
is calculated upon its value, not "internal address"– Alex Salauyou
Nov 14 '18 at 12:18
String#hashCode
is calculated upon its value, not "internal address"– Alex Salauyou
Nov 14 '18 at 12:18
add a comment |
@AlexSalauyou st1 += " E". so st1, shouldn't it hold the reference to "C D E" in string constant pool?
– shanika yrs
Nov 14 '18 at 11:05
@AlexSalauyou pretty sure
st1 += " E"
is just the short form ofst1 = st1 + " E"
and both will produce the same bytecode and in fact change/reassignst1
– OH GOD SPIDERS
Nov 14 '18 at 11:06
@OHGODSPIDERS shame on me ) thanks
– Alex Salauyou
Nov 14 '18 at 11:07
6
The reason is that in first case "A" + "B" is evaluated to constant "AB" in compile time, thus result is taken from the pool on instance initialization. In second case, you perform operation in code flow. There is no guarantee that equivalent Strings are same object until you adjust them calling
String#intern
– Alex Salauyou
Nov 14 '18 at 11:08
1
docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5
– Alex Salauyou
Nov 14 '18 at 11:12