-1

First of all, I searched about this in both S.O. and Google. If you say this is a duplicate of something somewhere, that something is being really hard to reach.

Well... we know Strings are Objects and must be compared by using equals, right?

Then, please, explain that:

String s1 = new String("string");
String s2 = new String("string");
String s3 = "string";

System.out.println(s1.equals(s2));  // true
System.out.println(s1 == s2);       // false

System.out.println(s1 == "string"); // false
System.out.println(s2 == "string"); // false
System.out.println(s3 == "string"); // true

Regarding the == "string" outputs, why does only the last one prints "true"?

When they're created, they aren't all Strings? Is now my third String the ugly duckling? ...Worse: if I'm working with a foreign String... it may not be the String that I think it is?! (Notice that s3 has String before it, not some primitive.)

...I'm pretty sure s3 has an object inside it.

In other words, what's the difference between declaring a String like this:

String s1 = new String("string");

and another like this:

String s3 = "string";

?

  • 1
    Re: "I searched about this in both S.O. and Google": If you add the word `intern` to your searches -- or just look up the Javadoc for `String.intern` -- you'll have more luck. – ruakh Dec 02 '12 at 17:39
  • 1
    Nice. This means I have to know the existence of this `intern` you know, which I didn't know. –  Dec 02 '12 at 17:40
  • 1
    The ***Related*** questions to your right mean you really didn't search hard enough. – Perception Dec 02 '12 at 17:41
  • @UndeoV.E.: Yes, I wasn't criticizing. Sometimes it's hard to find an answer that you don't already more-or-less know. – ruakh Dec 02 '12 at 17:41
  • @EJP Thanks, that helps, but it's hardly a duplicate. Although the OP got to something similar after some EDITs, the main question was the total opposite. –  Dec 02 '12 at 17:51

4 Answers4

3

When you do String s1 = new String("string");, it creates a new String object in the memory and holds the reference through s1. Similary by String s2 = new String("string");, you get another String object reference through s2.

== operator compares the object references hence s1 == s2 is false because they are difference string objects.

When you say String s3 = "string";, it creates an String constant literal object in internal pool (String class maintains internal pool) and assigns the reference to s3.

More details in the specification below:

All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification

Now when you say, s3=="string", "string" is referencing the same String object reference as s3(Java does the optimization in creating anonymous constant literal so same value literals are not created again). Thus this comparison is resulting into true.

This is not the case with s1 and s2 as each are referring an explicit String objects in memory.

Yogendra Singh
  • 33,927
  • 6
  • 63
  • 73
0

The compiler will search for hardcoded literals like "string", and replace them with the same reference object.

Your other two objects should return true on equals(), but they are different object's at all, because you're using the new operator.

Martin Seeler
  • 6,874
  • 3
  • 33
  • 45
  • 1
    Re: "if they occure often": Not true. Interning occurs for *all* string literals (and other compile-time constant string expressions), not just ones that occur often. See [§3.10.5 "String Literals" of *The Java Language Specification*, Java SE 7 Edition](http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5). – ruakh Dec 02 '12 at 17:43
  • my fault, thanks for that hint! – Martin Seeler Dec 02 '12 at 17:45
0

Some values of String type can be interned, that is, several instances of String having equal value can point to the same object. For such instances == will work correctly, although you can't rely on this behavior, unless you called intern() explicitly.

You can try following snippet which will always print true:

    String s1 = new String("a").intern();
    String s2 = "a".intern();

    System.out.println(s1 == s2);
Victor Sorokin
  • 11,878
  • 2
  • 35
  • 51
0

I hope you know about SCP(string constant pool) in java. When you create string using new it will create new reference like normal java object... But when you declare like s3 = "string " it will create reference in SCP only once for same value string.It means if you create any other like s5 = "string" it will point same reference it won't create new reference. == will check only reference but .equals() method check value. In your program "string" string value already stored in scp area so when you check s3 == "string " its returning true. Its not creating new reference. If you want more clarety post comment...

Kanagaraj M
  • 956
  • 8
  • 18