3
String S1="He";
String S2="llow";
String S3="Hellow";
String S4="He"+"llow";
String S5=S1+S2;
System.out.println(S3==S4); // prints true
System.out.println(S5==S3); // prints false
System.out.println(S5==S4); // prints false

why S5 is not referring object from constant pool? since S3 and S4 are in pool thats why giving true on S3==S4 but in case of S5==S3 & S5==S4 result is false,means S5 is not in pool.

Grimxn
  • 22,115
  • 10
  • 72
  • 85
TheCurious
  • 593
  • 1
  • 4
  • 29
  • You might need this http://stackoverflow.com/questions/13450392/why-are-equal-java-strings-taking-the-same-address/13450446#13450446 – Parth Soni Apr 02 '15 at 12:58

7 Answers7

5

The strings s1 through s4 are all compile time constants.

The compiler calculates "He" + "llow" during compile time, and consults the string pool as to whether the result is already there, and puts it there if it doesn't.

But the calculation of s1 + s2 is not done in compile time, and therefore its result is not interned. Why? Because in theory, another thread could change the value of s1 or s2 so by the time we get to this instruction in the code, it may set s2 to "foo", so the result becomes "Hefoo".

You, as the author, may know that no thread will be doing that and that these are local variables anyway, but the compiler doesn't.

If you change your definitions to:

    final String s1="He";
    final String s2="llow";
    final String s3="Hellow";
    final String s4="He"+"llow";
    final String s5=s1+s2;

Then indeed, the result of s5 == s3 will be true! Why? Because the final keyword lets the compiler know that these strings are not going to be replaced, they are the final value of these variables. So it can calculate it in compile time and take the result that is already in the pool.

RealSkeptic
  • 33,993
  • 7
  • 53
  • 79
2

from JLS

https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.

Strings computed by concatenation at run time are newly created and therefore distinct.

In the case of String S4, you're doing compile time concatenation,

String S4="He"+"llow";
therefore, it refers to the same object as S3

however , S1+S2 is a concatenation at run time , therefore , it refers to separate String object than S3 even though S1 + S2 and S3 are meaningfully equivalent . i.e (S1+S2).equals(S3) would return true

you can put a String in pool using intern method

Sarabjeet
  • 264
  • 2
  • 17
  • I got a point S5 resolve at run time.I am adding in my question--- if in this code we add same s6=s1+s2;then what will be output on s5==s6 and why? – TheCurious Apr 02 '15 at 13:24
  • it wud be false since they both are resolved at run time .Strings resolved at run time are created as distinct objects on heap . Only literal Strings and literal String concatenation at compile time can be placed in String pool – Sarabjeet Apr 02 '15 at 13:35
2

Since in String S4="He"+"llow"; Object create in pool and this is compile time constant same as S3="Hellow"; both are same object in pool but S5 created in heap at run time.

0

String literals that are concatenated are entered into the String pool. A String resulting from concatenation of variables however is not. That is why S3 is equal to S4 but not S5. They are not referring to the same object. However, (although I haven't tested this out) S5.equals(S4) should return true.

SchonWieder
  • 213
  • 2
  • 7
  • since S3 and S4 also referring the same object from constant pool.as you told s5 will refer from pool means S5 will also refer the same object,then why s5==s4 & s5==s3 giving false. – TheCurious Apr 02 '15 at 13:09
  • @dubey-theHarcortians S5 does not refer from the pool because S5 is created at runtime as a new String, based on the variables S3 and S4, which are literal values and therefore entered in to the pool at compile time. – SchonWieder Apr 02 '15 at 13:17
  • thanks.got a point S5 resolve at run time.I am adding in my question--- if in this code we add same s6=s1+s2;then what will be output on s5==s6 and why? – TheCurious Apr 02 '15 at 13:29
0
System.out.println(S3==S4);//true

Because S4 = "He"+"llow"; is optimised by the compiler and lead to the same string as "Hellow" which is shared with S3, hence S4 and S3 have the same reference.

System.out.println(S5==S3);//false

Because S5 and S3 are 2 distinct objects with different references.

System.out.println(S5==S4);//false

Same thing as before.

When you compare objects, you usually want to compare the content (with equals() and not the address/reference (with ==).

T.Gounelle
  • 5,953
  • 1
  • 22
  • 32
0

In general the compiler interns constant strings - even the ones created by a concatenation. That is why S3 and S4 are the same object.

S5 however is evaluated at runtime, that is why it creates a new object, distinct (but equal to) S4. If you put it into the string pool yourself, you will again get the same object as S4, so S5.intern() == S4 would be true.

Note that S5 not being the same as S4 is not guaranteed. A more optimizing compiler could put it into the string pool at compile time.

Gregor Raýman
  • 3,051
  • 13
  • 19
  • if in this code we add same s6=s1+s2;then what will be output on s5==s6 and why? – TheCurious Apr 02 '15 at 13:22
  • since s1+s2 would be evaluated twice, once for s5 and once for s6, s5==s6 would return false. But as said, don't rely on that. A clever compiler could optimize the second evaluation away. – Gregor Raýman Apr 02 '15 at 13:25
-1

compare string in java use equals

in a java objects == compare memory adresses

String S5=S1+S2;

S1+S2 return new string object

some objet have distinct memory adress you may compare use equals

System.out.println(S5.equals(S4));

if you concat many string objects use StringBuilder they fowing fasted and use minimum memory