Java文本优化,测试行为



我有一个小程序在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);
}

结果是:

true
true
true
false
false

字节码(javap-cMyClass)

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
}

问题)

1) 我看到system.out.println证实了a和b是相同的对象以下两者之间有什么区别:System.out.println(a == b);System.out.println(a.intern() == b);

2) 由于JVM在NonHeap PermanentGeneration InternetStrings中放入相同的String文字,String优化是否正在工作?这就是创建InternetString的原因吗?那么,为什么即使没有a.intern(),这也是相等的:a==b

两者之间有什么区别:System.out.println(a==b);System.out.println(a.internal()==b);

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

由于JVM在NonHeap PermanentGeneration InternetStrings中放入相同的字符串文字,字符串优化是否正在工作?这就是创建InternetString的原因吗?那么,为什么即使没有.intern(),这也是相等的:a==b

因为编译器和JVM协同工作,可以自动插入字符串文字。编译器将它们放在类文件的一个称为"常量池"的部分中,JVM在加载类时将这些常量加载到内部池中。


只是为了让普通读者更清楚:在Java中比较字符串的正确方法是使用.equals方法或类似方法,而不是==。将==与字符串实例一起使用通常是不正确的。OP可能在这里使用它是为了了解字符串是如何以及何时被插入的;在真正的代码中,你不会。(同样:new String("foo")在最好的情况下几乎总是不必要的,而且更可能是一个坏主意。同样,除非你在考虑何时以及如何练习琴弦。)

最新更新