0

I am new to JAVA programming. I have read it in my book

String a="Hello";
String b="Hello";
System.out.println(a==b);

This should return false as a & b refer to different instances of String objects.

Bcoz the assignments operator compares the instances of objects but Still I am getting a true.
I am using Eclipse IDE.

Example in book goes as this:

String s = "s";
String sToo = "s";
System.out.println(a == b);
System.out.println(s == sToo);

That bit of code prints “false” for s == sToo. That's because s and sToo are references to different instances of the String object. So, even though they have the same value, they are not equal in the eyes of the equality operators. Also, s == “s” prints false, because the string literal produces yet another instance of the String class.

Name of book: JAVA 7 for Absolute Beginners

chetan mehta
  • 369
  • 1
  • 3
  • 13
  • 6
    No, the values of `a` and `b` refer to the same object, due to string interning. Are you sure that the book gives that *exact* example? Also note that the *assignment* operator doesn't perform a comparison at all. The assignment operator is `=`; perhaps you were thinking of the equality operator, `==`? – Jon Skeet Oct 06 '13 at 16:03
  • 2
    To see how it can return false, try `String a=new String("Hello"); String b = "Hello";` – Flavio Oct 06 '13 at 16:04
  • Sorry really made the type .was thinking about assignment operator. Really sorry – chetan mehta Oct 06 '13 at 16:06
  • 3
    If that's really what the book says, then read another book. – JB Nizet Oct 06 '13 at 16:07
  • @JonSkeet ya I was thinking abt Comparison operator – chetan mehta Oct 06 '13 at 16:10

1 Answers1

8

This is an optimisation called string pooling in which compile-time constant Strings (aka known to be identical at compile time) can be set such that they really are the same object in memory (saving space for one of the most used types of object). Or in the words of the docs;

"All literal strings and string-valued constant expressions are interned."

Note that this only applies to Strings that are defined at compile time, so the following truly would print false.

String a="Hello";
String b=new String("Hello");
System.out.println(a==b); //prints false because a new string was forced

or

String a="Hello";
String b1="He";
String b2="llo";
String b=b1+b2;

System.out.println(a==b); //prints false because b wasn't know to be "Hello" at compile time so could not use string pooling

N.B. It is possible to cause the second snippet to print true by making b1 and b2 final, allowing b1+b2 to be known at compile time. All in all you need to be very careful and treat string==string with considerable respect, in the vast majority of cases you want string.equals(string) in which this behaviour does not exist.

Richard Tingle
  • 16,906
  • 5
  • 52
  • 77
  • 1
    The book (a) doesn't know what its talking about or (b) was written before this optimisation was included within java, you can only hope its (b) – Richard Tingle Oct 06 '13 at 16:16
  • the book was published in 2012 by Apress. so i think it is new .May be missing at that point. – chetan mehta Oct 06 '13 at 16:17
  • ya it does actually print true. – chetan mehta Oct 06 '13 at 16:19
  • @JB Nizet One last Question: String a="" behaves as primitive and String a=new String("") makes the a String object.Is IT??? – chetan mehta Oct 06 '13 at 16:20
  • 1
    @chetanmehta No, both are objects, however the compiler tries to be "clever" and combine them into several references all pointing to the same **object** when they are known to be the same at compile time – Richard Tingle Oct 06 '13 at 16:24
  • 4
    It's not just string literals that are interned -- it's any compile-time constant `String` expression. In your last example, for instance, declare `b1` and `b2` to be `final` variables would make `b1+b2` a compile-time constant expression. – Ted Hopp Oct 06 '13 at 16:27
  • 1
    Almost good enough for a +1, but the N.B. should read "cause the second snippet to print **true** . . .". Also, I'd rather see [the docs](http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#intern%28%29) quoted: "All literal strings and string-valued constant expressions are interned." – Ted Hopp Oct 06 '13 at 16:35
  • 1
    @TedHopp Thanks for your help, I must admit I've learnt quite a bit in answering this question too over and above my initial simplistic understanding (which isn't really the idea but hey-ho) – Richard Tingle Oct 06 '13 at 16:54