Java - 文字优化,测试行为

时间:2015-05-02 10:50:50

标签: java jvm literals

我有一个小程序在Java中测试文字行为。

NOTE_DELETE

结果是:

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);
}

字节码(javap -c MyClass)

true
true
true
false
false

问题)

1)我看到 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 } 确认,a和b是相同的对象 有什么区别: system.out.println         System.out.println(a == b);

2)System.out.println(a.intern() == b);最优化是否正常工作因为JVM在NonHeap-PermanentGeneration-InternedStrings中放置了相同的String文字?这就是创建InternedString的原因吗?那么为什么即使没有String这也是平等的:a.intern()

1 个答案:

答案 0 :(得分:2)

  

有什么区别:System.out.println(a == b); System.out.println(a.intern()== b);

只有第二个涉及完全不必要的方法调用。

  

字符串优化是否正常工作因为JVM在NonHeap-PermanentGeneration-InternedStrings中放置相同的字符串文字?这就是创建InternedString的原因吗?那么为什么即使没有a.intern()也是如此:a == b

因为编译器和JVM一起工作以自动实习字符串文字。编译器将它们放在类文件的一部分中调用&#34; constant pool,&#34;

。加载类时,JVM loads those constants进入实习池。

为了清楚偶然的读者:在Java中比较字符串的正确方法是使用.equals方法或类似方法,而不是==。将==与字符串实例一起使用通常不正确。 OP大概是在这里使用它来努力理解字符串是如何以及何时被实现的;在实际代码中,你不会。 (同样地:new String("foo")几乎总是不必要的,而且更可能是一个坏主意。再次,除非你正在玩弄字符串的时间和方式。)