Strange behavior with string interning in Java

后端 未结 4 1647
别跟我提以往
别跟我提以往 2020-12-14 10:21

There is code as following:

String s = new String(\"1\");
s.intern();
String s2 = \"1\";
System.out.println(s == s2);

String s3 = new String(\"1\")+new          


        
4条回答
  •  独厮守ぢ
    2020-12-14 10:49

    For the scenario 1:

    String s = new String("1");
    s.intern();
    String s2 = "1";
    System.out.println(s == s2);
    

    with bytecode:

       0: new           #2                  // class java/lang/String
       3: dup
       4: ldc           #3                  // String 1
       6: invokespecial #4                  // Method java/lang/String."":(Ljava/lang/String;)V
       9: astore_1
      10: aload_1
      11: invokevirtual #5                  // Method java/lang/String.intern:()Ljava/lang/String;
      14: pop
      15: ldc           #3                  // String 1
    

    for String s = new String("1"); it will create a new String object, it will have a new address with "1" that it is already in String Pool:

    ldc #3 // String 1

    and for s2, as the bytecode:

    15: ldc #3 // String 1

    s2 is pointing to String Pool variable: "1", so s and s2 have the different address and result is false.

    For the scenario 2:

    String s3 = new String("1")+new String("1");
    s3.intern();
    String s4 = "11";
    System.out.println(s3 == s4);
    

    with bytecode:

       0: new           #2                  // class java/lang/StringBuilder
       3: dup
       4: invokespecial #3                  // Method java/lang/StringBuilder."":()V
       7: astore_1
       8: aload_1
       9: ldc           #4                  // String 1
      11: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      14: ldc           #4                  // String 1
      16: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: invokevirtual #6                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      22: astore_2
      23: aload_2
      24: invokevirtual #7                  // Method java/lang/String.intern:()Ljava/lang/String;
      27: astore_3
      28: ldc           #8                  // String 11
    

    As the bytecode, you can see new String("1")+new String("1"); is created by using StringBuilder

    new #2 // class java/lang/StringBuilder

    it's totally a new Object without String Pool variable.

    and after s3.intern(), this method will add current s3 to the Memory String Pool and 8: aload_1.

    and s4 is trying to load from

    ldc #8 // String 11

    so s3 and s4 address should equal and result is true.

提交回复
热议问题