Disclaimer: This is suitable for java beginners only. Some questions are ever green interview questions. Java’s special treatment for String with respect to memory handling is a favourite area for java interviewers. Sometimes we even get bored of this play with String equals. I have written a detailed tutorial on java string and its immutable property, comparing strings and conversion. I think its time interviewers stop asking this question.
Last week a reader sent me the following puzzle and asked me to explain it.
public class StringEquals { public static void main(String[] args){ jack(); jill(); } public static void jack() { String s1 = "hill5"; String s2 = "hill" + "5"; System.out.println(s1==s2); } public static void jill() { String s1 = "hill5"; String s2 = "hill" + s1.length(); System.out.println(s1==s2); } }
I would classify this as a beginner level puzzle for java. To solve this we need fundamental knowledge on how String is instantiated and memory is allocated for it and that is sufficient. This is not a magnificent puzzle and if you have intermediate java knowledge you may not find it interesting. But still for the betterment of our java beginners and yet again I am writing this fundamental article.
Guys by the look of it we know one method is going to return true and another one false. Now lets find out what is the answer and why? When we run the program, jack prints true and jill prints false.
Because, when a string object is instantiated it cross checks with a memory pool if that String is already created. If it is already created then it maps the new variable to the already existing variable. Therefore both these variables are same objects. In jack() at compile time java knows that both the object are same and uses the same instance for referring to it.
In jill, too many things happens. First “hill” is created as a String object, then a new StringBuilder object is created which will help in concatenating two values. After the concatenation is done then it is converted back to a new String object. Real values are known at runtime only.
== operator with respect to String does not checks for the contents of String object. It checks if the compared String object has same reference value or not. Does it point to the same location or not? In jill case, though the value are same the reference is different and so it returns false.
Comments are closed for "String Equals Java Puzzle".
trick and track :)
Nice.. thanks.
Gud explanation for beginners.
what is the java command to print this information..
Good one…
Great.
It’s not only for beginners.
How to print this Code.
Interesting Joe..
Thanks such a nice explanation …
Nice thought….
Well done,……
Thanks.
Thanks ….
nice explanation. Can u explain a little more about String pool??
well explained.. thank you
Joe the interesting piece was the inner stack trace you have displayed.
Could you please share how to get this.
nice…..
Friends,
javap is a tool that is available as part of JDK and it can be found at JDK_HOME\bin
It is a java class disassembler.
Command: javap -c
prints the disassembled binary code. Using this I got the above information shown as image.
Excellent..as usual
Thanks for lot of information JOE
marvellous……really joe it is for all begginers and masters..to know these basic concepts….
Nice one buddy!!. keep posting ..
you are an excellent java tutor buddy….carry on…thanks
Respected Sir,
I am very proud of you sir. your explanations are so super. your example very good.i appreciate your work definitely. if you like i will join with you.
In method jack(), why isn’t a new object of String “hill” created and then a StringBuilder object help appending the primitive 5, finnally returning a new string?
thanks:)
Thanks Joe :-) very nice explanation….
Hi Joe,
please wil you elobrate more on how to use java class disassembler!!!
Joe
Please post an article with basic questions of sql or pl/sql asked in interviews.
Thanks in Advance!!!
Thanks Sir…. Good Job
Nice……. and Thank you
Nice article..explains the basic things in a simple yet effective way..
Thank you!!!
Nice One. Add more post for Java.
Hi Joe,
I tried this example by adding some more sout code with the hashcode values.
—-
public class StringEquals {
public static void main(String[] args){
jack();
jill();
}
public static void jack() {
String s1 = “hill5″;
System.out.println(” jack : S1 hashcode”+s1.hashCode());
String s2 = “hill” + “5”;
System.out.println(“jack : S2 hashcode”+s2.hashCode());
System.out.println(s1==s2);
}
public static void jill() {
String s1 = “hill5”;
System.out.println(“jill : S1 hashcode”+s1.hashCode());
String s2 = “hill” + s1.length();
System.out.println(“jill : S2 hashcode”+s2);
System.out.println(“jill : S2 hashcode”+s2.hashCode());
System.out.println(s1==s2);
}
}
—
Output is as below:
jack : S1 hashcode:99281428
jack : S2 hashcode:99281428
true
jill : S1 hashcode:99281428
jill : S2 hashcode:99281428
false
as == check only the reference and not the content and as i can see that the hashcode reference no is same for both jack and jill s1 and s2 object…then why one is True and one False ….
Please don’t mind as i am veru beginner of Java and a bit confused with this output..
Thanks for your effort :)
Yes previous question has to be answered. It is really making in confuse.
@Navin and @Jayesh…as shown in your example the values are same as also indicated by the hashcode but note that the “==” operator on strings checks for the memory locations and not for the values… in jack both the concatenations are on string itself but in jill the concatenation is on a string and a primitive number(int) so a stringbuilder will be used to concat and it returns a string object pointing to a new memory location…
can you plz tell me how to use print functions for the task like,to get print out by printer?
Like your previous articles, this is also great..Expecting more and more articles like this..
Hi Joe,
I still could not get the point why the references are not pointing t the same object in Jill’s case.I mean its hill5 only right,In both the cases?
Please put some light on this.
Thanks
Java has to determine if its the same string during the compile time. In jill() its creating the string during run time and its creating a new object in the heap. The hashcode for both the objects are the same because of the hashcode and the equals contract. If the equals() method evaluates to true (in our case it is) then the hashcode should be the same.
Excellent…Thanks for your efforts.
how to edit a class file and recompile in java?
Thanks
Can u pls tell me how to print this class ???
What happens when we use s1.equals(s2); In both the jill and jack functions.
thanx a lot!!
if in jack method i am using
s2=”hill”+5 then result is true
if int i=5
s2=”hill”+i then its true.
Why?
why the other operators EXCEPT ‘+’ are not used in STRING MANIPULATION?
hey Joe,
Very nice article, Thanks for sharing.
Its always a matter of confusion for beginners “checking strings”.
@Navin and @Jayesh
If you read the equals contract in Object class, it clearly specified that if two objects are equal then their hashCode has to be same but if two Objects have same hashCode then its not meant that they are equal.
Hope this will clear your doubts.
@shashwat
why – here is the answer.
you have concatenated an integer with a String, so the compiler has to use a String Builder for this, see Joe’s disassembled code.
Now the location of the resultant string after concatenation changed and the == check only the memory location, that’s why a false is returned.
Hope this will clear your doubt.
~cheers
Rakesh
@Rakesh-
You have not understood the Shashwat’s doubt.
His actual doubt is – in both cases concatenation is happening ,then why in Jill() only new string object is created in heap space.
Please help me with same.
am very much clear with == and equals.
@shashwat
probably its because for “hill” + 5 at complie time it is calculated and s2.length at run time.
@joe @rakesh correct me if I am wrong.
my query.
Why at run time StringBuilder is needed and how at compile time the reference is matched
@Shashwat
First of all int i = 5; s2 = “hill” +i; s1==s2 will give you false.
Reason is for constants/literals and final variables the concatenation is done at complie time, no StringBuffer s1==s2 true.
But if any of the piece is a variable like “hill” + i; the concatenation is done at run time using StringBuilder.
new StringBuilder(“hill”).append(i);
That is amazing article. When you say ‘it is for beginners’ Joe, what is there for intermediate and advanced users?
To achieve both functions true. you may use following program.
public class StringEquals {
public static void main(String[] args){
jack();
jill();
}
public static void jack() {
String s1 = “hill5”;
String s2 = “hill” + “5”;
System.out.println(s1==s2);
}
public static void jill() {
String s1 = “hill5”;
String s2 = “hill” + s1.length();
System.out.println(s1.equals(s2));
}
}
very helpful
In case of string how do you know string are different ,you will say using ‘==’ but if it returns false how to find hashcode,you will say hashcode,Then why hashcode is same but string object is different.
What is proper way to justify find different object in case of string.please please write the comment joe sir………….I am waiting for your comment.
Thanks for thos article.
public class HashCodeDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String s=new String(“demo”);
String s1=new String(“demo”);
System.out.println(s==s1);
System.out.println(s.hashCode());
System.out.println(s1.hashCode());
}
}
//output:
false
3079651
3079651
question :why different object have same hashcode,Is it proper way to classify the different object???
As contents of both objects are same hashcodes are same,== operator checks whether two referrences s,s1 are pointing to the same object or not ,here s,s1 are two different objects so it returns false
Clearing hashCode doubts.
Hashcode methods only returns an unique integer and as per contract if 2 objects are equal by equals method, then the hashcode must return the same integer.
Now java.lang.String class overrides hashcode method. Lets see the implementation
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
where value is char[] in which the String value is stored.
It is clear String hashcode returns the hash code value based on the character value of the String following the contract of hashcode.
Therefore same string returns same hashcode. It does not return the address.
Hi, what was the version of JDK used to check the byte code ?
With 1.6 I could see StringBuffer being used instead of StringBuilder in OpenJDK.
27: ldc #35 // String world1
29: invokespecial #37 // Method java/lang/StringBuffer.””:(Ljava/lang/String;)V
32: aload_2
33: invokevirtual #40 // Method java/lang/String.length:()I
36: invokevirtual #46 // Method java/lang/StringBuffer.append:(I)Ljava/lang/StringBuffer;
39: invokevirtual #50 // Method java/lang/StringBuffer.toString:()Ljava/lang/String;
42: astore_3
43: getstatic #21 // Field java/lang/System.out:Ljava/io/PrintStream;
46: aload_3
>java -version
java version “1.6.0”
OpenJDK Runtime Environment (build 1.6.0-b09)
What is difference between String s=”data”; and String s=new String(“data”);?
Hi Joe,
Its a nice tutorial, but I still have a doubt, please see the code segment below:
String s1=”abc”;
String s2=”def”;
String s3=”abcdef”;
String s4=new String(“abcdef”);
s1+=s2;
System.out.println(s1==s3);
System.out.println(s3==s4);
System.out.println(s1==s4);
Output of this is:
false
false
false
Could you please explain?
@ Rajlaxmi
s1, s2,s3 are referring to string literals created in string pool.
s4 is referring to a string created in the heap.
s1+=s2; this creates a new string in the heap and s1 is made to refer this.
s1==s3 here comparison is happening between the “abcdef” in pool and the “abcdef” in heap.
the same with s3==s4 and s1==s4.
Great Article…..Good work.
nice one
our stroy is kind of same
Hi sir…really awesome explanation. Now i got a clear idea on strings concept…
really nice comments… its cleared so many confusions on strings
Dear Joe,
Thanks a lot for this and your all other articles………….
I am a old reader of your blog……its really nice one….Your explanation are very close to the INDIAN IT professionals….
I expect One more favor from you………
I just want one complete article on String comparison covering all conditions for “==” and “equals” operator to mastermind this concept and evergreen preparation for first interview question of JAVA……
@Naveen – I tried the same, but i am getting the different hashcode for jill s2.
jack s1::22772102
jack s2::22772102
Jill s1::22772102
Jill s2::8880493