Java - Automatic String interning within constructors

99封情书 提交于 2020-01-04 08:10:19

问题


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.


回答1:


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

  • What is the Java string pool and how is "s" different from new String("s")?
  • How do I compare strings in Java?



回答2:


The field apple within Apple is a reference to a String.

In your case that reference is referring to an interned string, since you've instantiated the Apple using a string literal which will be interned.

And since a and b are created from the same interned string, a.apple refers to the same string as b.apple.

Indeed Java cannot intern a string if you use new String.



来源:https://stackoverflow.com/questions/38325619/java-automatic-string-interning-within-constructors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!