2

I was kind of telling some one that , we must use String.equals method to compare two strings values, we can not simply use == operator in java to compare Strings, and told him that == will return false as it doesn't compare the string value but String object reference value.

I have written this example to show him, but for my surprise it always prints true for == operator.. here is the code

public void exampleFunc1(){

    String string1 = "ABC";
    String string2 = "ABC";

    if(string1 == string2)
        System.out.println("true");
    else{
        System.out.println("false");

    }   
    System.out.println(" Are they equal "+(string1 == string2)); // this shouldn't print True but it does
    System.out.println(" Are they equal "+(string1.equals(string2)));

}

Output:-

Are they equal true

Are they equal true

So question here is in what circumstances == operator on objects can print true, except that both objects are same instance?

1
  • 1
    See the answer to String comparison and String interning in Java, which points out that compile-time constants can be interned so two literals end up refering to the same string object. Commented Sep 1, 2013 at 5:01

3 Answers 3

2

String is one of a few special cases.

Class String keeps a special pool of "interned" Strings. Method myString.intern() looks up myString in this pool. If another String with the same contents already exists in the pool, a pointer to it is returned. If not, myString is added (and a pointer returned).

When you say myString= myString.intern() ;, you are effectively making myString refer to a shared copy or its underlying String available for future sharing (and no duplication). Most library methods creating Strings are subject to this, particularly String literals.

Other cases of "interning" occur with wrapper types Integer, Long, etc. They don't have constructors, but static methods valueOf() that return pre-built, shared objects when they can (usually the 256 values closest to zero), and new objects when they can not. The later is not much problematic because these types are more lightweight than Strings. Long, for example, has a payload of just 8 bytes. String contains a char[] that even empty is 16 bytes or so.

To answer your question, you can not count on any "interning" mechanisms. They have changed in the past, and they could change in the future (or even from one JVM to another), making your code unusable. Always use equals.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks, And what happens if we change one string value
@Ankit How? With concatenation? My impression is that concatenation interns the result. With String functions? Same thing. The only escape to this is to force the creating of new Strings by using String constructors. If the Java team had thought of interning before, these would not exist, and things would be similar to wrapper types (no constructors, just constructor-like static methods).
thats sound nice, Thanks :) , Happy coding.
1

You should use

String string1 = new String("ABC");

String string2 = new String("ABC");

Then everything would be correct like what you think,

In this case, "ABC" is just a reference to a const string.

1 Comment

@Ankit That's because new forces a new String to be created. Constructors can't return a different object than the one they are constructing. However, if you subject both strings to interning, you will be back to string1 == string2.
0

The compiler may be optimizing the assignments and only creating one String object. If you use the explicit String constructor, the == operation should behave as expected.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.