1. 程式人生 > >檢視位元組碼 javap -v xxx.class

檢視位元組碼 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

 

}