3
public class Test {
    int multiple;
    public static void main(String[] args){

        String string1 = "string";
        String string2 = "string";
        String string4 = "Changed";

        String string3 = new String("string");

        System.out.println("string1 == string2: " + (string1 == string2));\\true
        System.out.println("string1 == string4: " + (string1 == string4));\\false
        System.out.println("string1 == string3: " + (string1 == string3));\\false

    }


}

I understand that the == operator will return true if the references are same. What I want to know is, Does Java check the content of string literals before creating their objects?

prometheuspk
  • 3,754
  • 11
  • 43
  • 58

2 Answers2

4

You're seeing one of the side effects of Java string interning. From the JLS §3.10.5:

...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" so as to share unique instances, using the method String.intern.

Lots more reading on SO, especially:

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • It's worth noting here that the JLS appears to be incorrect. The compiler can't use String.intern() for this purpose, as the process described happens at compile time, not runtime. – user207421 Apr 15 '12 at 22:42
  • @EJP what you say doesn't really make sense. Where does the JLS say anything about interning happening at compile time (viz. _"the compiler can't use String.intern() for this purpose"_)? The constant expressions are _identified_ at compile time, and the `String#intern()` call is inserted by the compiler, but the method isn't actually _called_ until runtime. Heck, the intern pool doesn't exist until runtime. Correct me if I've misunderstood your comment. – Matt Ball Apr 15 '12 at 23:39
  • Erm, where does it say anything about the compiler or compile time? – Matt Ball Apr 15 '12 at 23:53
  • It's talking about string literals and constant-valued string expressions. Only the compiler can even see either of those. To the JVM they are all just String objects. – user207421 Apr 16 '12 at 00:15
3

It is the compiler that does the string interning. So at compile time identical strings are optimised. So I think the answer you want is "no". The Virtual Machine doesn't do it, it is the compiler. You can call String.intern() to acquire the shared string object in the string pool:

String str1 = "string";
String str2 = new String("string");
String str3 = str2.intern();

str1 == str2 // false
str2 == str3 // false
str1 == str3 // true

Strings, build at runtime are not interned automatically.

Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
  • Is it right to say that `intern()` basically checks whether the content is same or not – prometheuspk Apr 15 '12 at 15:49
  • No, it checks if it has that string on which you call the method, is already in the string pool. If so, it returns the reference from the pool. If not, it creates a new string in the pool and returns that reference. – Martijn Courteaux Apr 15 '12 at 15:54
  • Yes, it is content based. But, I think it uses hashCodes, to optimise. – Martijn Courteaux Apr 15 '12 at 16:13
  • [`String.intern()` is a native function (in OpenJDK, at least)](http://www.docjar.com/html/api/java/lang/String.java.html#3071); consequently, I doubt it uses `hashCode()`. I recall seeing a version of `java.lang.String` which was not native, but delegated to the native `VM.intern()` method, though of course I can't dig it up now... – Matt Ball Apr 15 '12 at 17:18