问题
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