wild_nothing wild_nothing - 4 months ago 10
Java Question

Java - Automatic String interning within constructors

Let's say I have a class as follows:

class Apple {

String apple;

Apple(String apple) {
this.apple = apple;
}
}


What makes the following code true?

public boolean result() {
Apple a = new Apple("apple");
Apple b = new Apple("apple");

return a.apple == b.apple;
}


Does Java automatically intern Strings set within instances of my objects?

Is the only time that Java doesn't intern Strings is when they're created using
new String("...")
?

EDIT:

Thanks for the answers, an extension to this question would then be to say

Apple a = new Apple(new String("apple"));
Apple b = new Apple(new String("apple"));


returns false with the same test.

This is because I am passing an instance of String into the constructor as opposed to a String literal.

Answer

Does Java automatically intern Strings set within instances of my objects?

The point is: when you create first Apple a, JVM provide an instance of String containing "apple". This String is added to StringPool.

So when you create the second Apple b, the String is reused, then you have same object reference in a.apple and b.apple:

EXAMPLE:

Apple a = new Apple("apple");
Apple b = new Apple(new String("apple"));

System.out.println(a.apple == b.apple);

OUTPUT:

false

Is the only time that Java doesn't intern Strings is when they're created using new String("...")?

If you compare String objects with == you compare object references, not content.

To compare the contents of a String use String::equals() or String::intern()

EXAMPLE

    // declaration
    String a = "a";
    String b = "a";
    String c = new String("a");

    // check references 
    System.out.println("AB>>" + (a == b));  // true, a & b references same memory position
    System.out.println("AC>>" + (a == c));  // false, a & c are different strings
    // as logic states if a == b && a != c then b != c.

    // using equals
    System.out.println("ACe>" + (a.equals(c))); // true, because compares content!!!!

    // using intern()
    System.out.println("ABi>" + (a.intern() == b.intern()));  // true
    System.out.println("BCi>" + (b.intern() == c.intern()));  // true

RELATED QUESTIONS