Reputation:
I have a small program testing literals behaviour in Java.
public static void main(String[] args) {
String a = "foo";
String b = "foo";
String c = new String("foo");
System.out.println(a == b);
System.out.println(a.intern() == b);
System.out.println(a.intern() == a);
System.out.println(a == c);
System.out.println(c == b);
}
The results are:
true
true
true
false
false
The bytecode (javap -c MyClass)
public MyClass();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String foo
2: astore_1
3: ldc #2; //String foo
5: astore_2
6: new #3; //class java/lang/String
9: dup
10: ldc #2; //String foo
12: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/String;)V
15: astore_3
16: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
19: aload_1
20: aload_2
21: if_acmpne 28
24: iconst_1
25: goto 29
28: iconst_0
29: invokevirtual #6; //Method java/io/PrintStream.println:(Z)V
32: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
35: aload_1
36: invokevirtual #7; //Method java/lang/String.intern:()Ljava/lang/String;
39: aload_2
40: if_acmpne 47
43: iconst_1
44: goto 48
47: iconst_0
48: invokevirtual #6; //Method java/io/PrintStream.println:(Z)V
51: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
54: aload_1
55: invokevirtual #7; //Method java/lang/String.intern:()Ljava/lang/String;
58: aload_1
59: if_acmpne 66
62: iconst_1
63: goto 67
66: iconst_0
67: invokevirtual #6; //Method java/io/PrintStream.println:(Z)V
70: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
73: aload_1
74: aload_3
75: if_acmpne 82
78: iconst_1
79: goto 83
82: iconst_0
83: invokevirtual #6; //Method java/io/PrintStream.println:(Z)V
86: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
89: aload_3
90: aload_2
91: if_acmpne 98
94: iconst_1
95: goto 99
98: iconst_0
99: invokevirtual #6; //Method java/io/PrintStream.println:(Z)V
102: return
}
Questions)
1) I see that system.out.println
confirms, that a and b are the same objects
What are the difference between:
System.out.println(a == b);
System.out.println(a.intern() == b);
2) Is the String
optimalization is working becaouse JVM puts the same String
literals in NonHeap-PermanentGeneration-InternedStrings? Is that why InternedString were created? Then why even without a.intern()
this is equal: a==b
Upvotes: 1
Views: 83
Reputation: 1075139
What are the difference between: System.out.println(a == b); System.out.println(a.intern() == b);
Only that the second involves an entirely unnecessary method call.
Is the String optimalization is working becaouse JVM puts the same String literals in NonHeap-PermanentGeneration-InternedStrings? Is that why InternedString were created? Then why even without a.intern() this is equal: a==b
Because the compiler and JVM work together to automatically intern string literals. The compiler puts them in a section of the class file calls the "constant pool," and the JVM loads those constants into the intern pool when the class is loaded.
Just for clarity for casual readers: The correct way to compare strings in Java is to use the .equals
method or similar, not ==
. Using ==
with string instances is usually incorrect. The OP is presumably using it here in an effort to understand how and when strings are interned; in real code, you wouldn't. (Similarly: new String("foo")
is almost always at best unnecessary, and more likely actively a bad idea. Again unless you're playing around with when and how strings are interned.)
Upvotes: 2