查看字节码 javap -v xxx.class

public static void main(String[] args) {

String s1 = "Hello";

String s2 = "Hel" + "lo";

String s3 = new String("Hello");

String s4 = "Hel" + new String("lo");

String s5 = s3.intern();

int i1 = 0;

int i2 = 1;

System.out.println(s1 == s2);

System.out.println(s1 == s3);

System.out.println(s3 == s4);

System.out.println(s2 == s4);

System.out.println(s1 == s2);

System.out.println(s2 == s5);

System.out.println(i1 == i2);

}

Constant pool:(常量池)

#2 = String #36 // Hello

#3 = Class #37 // java/lang/String

#5 = Class #39 // java/lang/StringBuilder

#7 = String #40 // Hel

#9 = String #42 // lo

{

stack=4, locals=8, args_size=1

0: ldc #2 // String Hello (加载常量池的#2号字符串压入栈)

2: astore_1 (将上一步加载的引用变量赋值给变量1,即s1【参照LocalVariableTable的slot数值】)

3: ldc #2 // String Hello (加载常量池的#2号字符串压入栈)

5: astore_2 (将上一步加载的引用变量赋值给变量2,即s2【参照LocalVariableTable的slot数值】)

6: new #3 // class java/lang/String (创建#3号的实例:java/lang/String)

9: dup (复制上一步创建的对象的引用压入栈)

10: ldc #2 // String Hello (加载常量池的#2号字符串压入栈)

12: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V (调用String的init方法,将上一步加载入栈的引用作为参数传入init方法)

15: astore_3 (将上一步返回的引用变量赋值给变量3,即s3【参照LocalVariableTable的slot数值】)

16: new #5 // class java/lang/StringBuilder(创建#5号的实例:java/lang/StringBuilder)

19: dup (复制上一步创建的对象引用压入栈)

20: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V (调用StringBuilder的init方法)

23: ldc #7 // String Hel (加载常量池#7号字符串压入栈)

25: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; (调用StringBuilder的append方法,将上一步加载的引用作为参数传入append方法)

28: new #3 // class java/lang/String (创建#3号的实例:java/lang/String)

31: dup (复制上一步创建的对象的引用压入栈)

32: ldc #9 // String lo (加载常量池#9号字符串压入栈)

34: invokespecial #4 // Method java/lang/String."<init>":(Ljava/lang/String;)V (调用String的init方法,将上一步加载入栈的引用作为参数传入init方法)

37: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; (调用StringBuilder的append方法,将上一步加载的引用作为参数传入append方法)

40: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;(调用StringBuilder的toString方法)

43: astore 4 (将上一步返回的引用赋值给变量4,即s4【参照LocalVariableTable的slot数值】)

45: aload_3 (加载变量3压入栈)

46: invokevirtual #11 // Method java/lang/String.intern:()Ljava/lang/String; (调用String的intern方法)

49: astore 5 (将上一步返回的引用赋值给变量5,即s5【参照LocalVariableTable的slot数值】)

51: iconst_0 (将数字0压入栈)

52: istore 6 (将上一步加载的数字赋值给变量6,即i1【参照LocalVariableTable的slot数值】)

54: iconst_1 (将数字1压入栈)

55: istore 7 (将上一步加载的数字赋值给变量7,即i2【参照LocalVariableTable的slot数值】)

57: getstatic #12 // Field java/lang/System.out:Ljava/io/PrintStream; (调用System的静态方法out)

60: aload_1 (加载变量1,即s1)

61: aload_2 (加载变量2,即s2)

62: if_acmpne 69(比较s1和s2是否不相等,如果不相等,跳转到63行指令,如果相等则继续下一步,if_acmpne和if_icmpne,a表示对象引用比较,I表示数字比较;if_acmpeq和if_acmpne,eq【equal】表示相等,ne【not equal】)

65: iconst_1 (将数字1压入栈)

66: goto 70 (跳转到64行指令)

69: iconst_0 (将数字0压入栈)

70: invokevirtual #13 // Method java/io/PrintStream.println:(Z)V

……

156: getstatic #12 // Field java/lang/System.out:Ljava/io/PrintStream;

159: iload 6 (加载变量6,即i1)

161: iload 7 (加载变量7,即i2)

163: if_icmpne 170(比较i1和i2)

166: iconst_1

167: goto 171

170: iconst_0

171: invokevirtual #13 // Method java/io/PrintStream.println:(Z)V

……

150: return

LocalVariableTable:

Start Length Slot Name Signature

0 151 0 args [Ljava/lang/String;

3 148 1 s1 Ljava/lang/String;

6 145 2 s2 Ljava/lang/String;

16 135 3 s3 Ljava/lang/String;

45 106 4 s4 Ljava/lang/String;

51 100 5 s5 Ljava/lang/String;

54 121 6 i1 I

57 118 7 i2 I

}

猜你喜欢

转载自blog.csdn.net/luxiaoruo/article/details/85337512
今日推荐