user1308908
user1308908

Reputation:

Java - literals optimalization, test behaviour

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

Answers (1)

T.J. Crowder
T.J. Crowder

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

Related Questions