1)pop、pop2:將操做數棧的棧頂一個或兩個元素出棧。
2)dup、dup二、dup_x一、dup2_x一、dup_x二、dup2_x2:複製棧頂一個或兩個數值並將複製值或雙份的複製值從新壓入棧頂。
3)swap:將棧最頂端兩個數值互換。java
public static void main(String[] args) { heavyMethod(); }
對應的字節碼:數組
public static void main(java.lang.String[]); Signature: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=1, args_size=1 0: invokestatic #23 // Method heavyMethod:()I 3: pop 4: return LineNumberTable: line 115: 0 line 116: 4
1)iload、iload<n>、lload、lload<n>、fload、fload<n>、dload、dload<n>、aload、aload<n>:將一個局部變量加載到操做數棧。
2)istore、istore<n>、lstore、lstore<n>、fstore、fstore<n>、dstore、dstore<n>、astore、astore<n>:將一個數值從操做數棧存儲到局部變量表。
3)bipush、sipush、ldc、ldc_w、ldc2_w、aconst_null、iconstm一、iconst<i>、lconst<l>、fconst<f>、dconst_<d>:將一個常量加載到操做數棧。
4)wide:擴充局部變量表的訪問索引的指令。jvm
public static int methodE(){ int e = 100; int c = 300; int d = 300000; e++; ++e; --e; e--; return c + d + e; }
對應的字節碼:ide
public static int methodE(); Signature: ()I flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=3, args_size=0 0: bipush 100 2: istore_0 3: sipush 300 6: istore_1 7: ldc #5 // int 300000 9: istore_2 10: iinc 0, 1 13: iinc 0, 1 16: iinc 0, -1 19: iinc 0, -1 22: iload_1 23: iload_2 24: iadd 25: iload_0 26: iadd 27: ireturn LineNumberTable: line 40: 0 line 41: 3 line 42: 7 line 43: 10 line 44: 13 line 45: 16 line 46: 19 line 47: 22
1)iadd、ladd、fadd、dadd:加法指令。
2)isub、lsub、fsub、dsub:減法指令。
3)imul、lmul、fmul、dmul:乘法指令。
4)idiv、ldiv、fdiv、ddiv:除法指令。
5)irem、lrem、frem、drem:求餘指令。
6)ineg、lneg、fneg、dneg:取反指令。
7)ishl、ishr、iushr、lshl、lshr、lushr:位移指令。
8)ior、lor:按位或指令。
9)iand、land:按位與指令。
10)ixor、lxor:按位異或指令。
11)iinc:局部變量自增指令。
12)dcmpg、dcmpl、fcmpg、fcmpl、lcmp:比較指令。
參照上例。code
1)int類型到long、float或者double類型,long類型到float、double類型,float類型到double類型:寬化類型轉換(虛擬機直接支持)。
2)i2b、i2c、i2s、l2i、f2i、f2l、d2i、d2l、d2f:窄化類型轉換(顯式指令)。對象
public static void methodK(){ int i = 97; short i2s = (short) i; char i2c = (char) i; long i2l = i; float i2f = i; double i2d = i; float l2f = i2l; double l2d = i2l; }
對應的字節碼:索引
public static void methodK(); Signature: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=11, args_size=0 0: bipush 97 2: istore_0 3: iload_0 4: i2s 5: istore_1 6: iload_0 7: i2c 8: istore_2 9: iload_0 10: i2l 11: lstore_3 12: iload_0 13: i2f 14: fstore 5 16: iload_0 17: i2d 18: dstore 6 20: lload_3 21: l2f 22: fstore 8 24: lload_3 25: l2d 26: dstore 9 28: return LineNumberTable: line 100: 0 line 101: 3 line 102: 6 line 103: 9 line 104: 12 line 105: 16 line 106: 20 line 107: 24 line 108: 28
1)new :建立類實例的指令。
2)newarray、anewarray、multianewarray:建立數組的指令。
3)getstatic、putstatic、getfield、putfield:訪問類字段(類變量)和實例字段(實例變量)的指令。
4)baload、caload、saload、iaload、laload、faload、daload、aaload:把一個數組元素加載到操做數棧的指令。
5)bastore、castore、sastore、iastore、lastore、fastore、dastore、aastore:把一個操做數棧的值存儲到數組元素中的指令。
6)arraylength:取數組長度的指令。
7)instanceof、checkcast:檢查類實例類型的指令。接口
public static void methodJ(){ new SimpleMethodExecuteProcess(); System.out.println(SimpleMethodExecuteProcess.i); }
對應的字節碼:ip
public static void methodJ(); Signature: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=0, args_size=0 0: new #9 // class edu/atlas/demo/java/jvm/SimpleMethodExecuteProcess 3: dup 4: invokespecial #10 // Method "<init>":()V 7: pop 8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 11: getstatic #11 // Field i:I 14: invokevirtual #12 // Method java/io/PrintStream.println:(I)V 17: return LineNumberTable: line 91: 0 line 93: 8 line 94: 17
1)ifeq、iflt、ifle、ifne、ifgt、ifge、ifnull、ifnonnull、if_icmpeq、if_icmpne、if_icmplt、if_icmpgt、if_icmple、if_icmpge、if_acmpeq、if_acmpne:條件分支。
2)tableswitch、lookupswitch:複合條件分支。
3)goto、goto_w、jsr、jsr_w、ret:無條件分支。ci
public static void methodG(){ if(i == 0){ System.out.println(System.currentTimeMillis()); } while(i < 1){ System.out.println(System.currentTimeMillis()); i++; } }
對應的字節碼:
public static void methodG(); Signature: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=0, args_size=0 0: getstatic #6 // Field i:I 3: ifne 15 6: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 9: invokestatic #7 // Method java/lang/System.currentTimeMillis:()J 12: invokevirtual #8 // Method java/io/PrintStream.println:(J)V 15: getstatic #6 // Field i:I 18: iconst_1 19: if_icmpge 42 22: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 25: invokestatic #7 // Method java/lang/System.currentTimeMillis:()J 28: invokevirtual #8 // Method java/io/PrintStream.println:(J)V 31: getstatic #6 // Field i:I 34: iconst_1 35: iadd 36: putstatic #6 // Field i:I 39: goto 15 42: return LineNumberTable: line 62: 0 line 63: 6 line 66: 15 line 67: 22 line 68: 31 line 70: 42 StackMapTable: number_of_entries = 2 frame_type = 15 /* same */ frame_type = 26 /* same */
athrow :顯式拋出異常指令。
public static void methodH(){ try { throw new NullPointerException("nothing ..."); // do nothing ... } catch (Throwable t){ // do nothing ... } }
對應的字節碼:
public static void methodH(); Signature: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=1, args_size=0 0: new #9 // class java/lang/NullPointerException 3: dup 4: ldc #10 // String nothing ... 6: invokespecial #11 // Method java/lang/NullPointerException."<init>":(Ljava/lang/String;)V 9: athrow 10: astore_0 11: return Exception table: from to target type 0 10 10 Class java/lang/Throwable LineNumberTable: line 77: 0 line 79: 10 line 82: 11 StackMapTable: number_of_entries = 1 frame_type = 74 /* same_locals_1_stack_item */ stack = [ class java/lang/Throwable ]
monitorenter、monitorexit:支持synchronized語句塊語義的指令。
public void methodI(){ synchronized (Integer.class){ // do nothing ... } }
對應的字節碼:
public void methodI(); Signature: ()V flags: ACC_PUBLIC Code: stack=2, locals=3, args_size=1 0: ldc_w #13 // class java/lang/Integer 3: dup 4: astore_1 5: monitorenter 6: aload_1 7: monitorexit 8: goto 16 11: astore_2 12: aload_1 13: monitorexit 14: aload_2 15: athrow 16: return Exception table: from to target type 6 8 11 any 11 14 11 any LineNumberTable: line 88: 0 line 90: 6 line 91: 16 StackMapTable: number_of_entries = 2 frame_type = 255 /* full_frame */ offset_delta = 11 locals = [ class edu/atlas/demo/java/jvm/SimpleMethodExecuteProcess, class java/lang/Object ] stack = [ class java/lang/Throwable ] frame_type = 250 /* chop */ offset_delta = 4
- synchronized 修飾方法的語義解析:能夠直接從方法常量池的方法表結構中ACC_SYNCHRONIZED訪問標誌得知一個方法是否聲明爲同步方法,不須要解析出monitorenter、monitorexit同步指令。
public static synchronized void methodL(){ int i = 97; } public static synchronized void methodL(); Signature: ()V flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED Code: stack=1, locals=1, args_size=0 0: bipush 97 2: istore_0 3: return LineNumberTable: line 120: 0 line 121: 3
1)invokestatic:調用靜態方法。
2)invokespecial:調用實例構造器<init>方法、私有方法和父類方法。
3)invokevirtual:調用全部的虛方法。非虛方法之外的都是虛方法,非虛方法包括使用invokestatic、invokespecial調用的方法和被final修飾的方法。
4)invokeinterface:調用接口方法,運行時再肯定一個實現此接口的對象。
5)invokedynamic:用於在運行時動態解析出調用點限定符所引用的方法,並執行該方法。
ireturn(返回值是boolean、byte、char、short、int)、lreturn、freturn、dreturn、areturn:方法返回指令。
public static int heavyMethod(){ int a = 200; int b = 100; int c = methodC(methodA(methodA(a, b), b), methodB(a, b)); methodD(); methodE(); methodF(); methodG(); methodH(); new SimpleMethodExecuteProcess().methodI(); methodJ(); methodK(); methodL(); return c; }
對應的字節碼:
public static int heavyMethod(); Signature: ()I flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=3, args_size=0 0: sipush 200 3: istore_0 4: bipush 100 6: istore_1 7: iload_0 8: iload_1 9: invokestatic #17 // Method methodA:(II)I 12: iload_1 13: invokestatic #17 // Method methodA:(II)I 16: iload_0 17: iload_1 18: invokestatic #18 // Method methodB:(II)I 21: invokestatic #19 // Method methodC:(II)I 24: istore_2 25: invokestatic #20 // Method methodD:()V 28: invokestatic #21 // Method methodE:()I 31: pop 32: invokestatic #22 // Method methodF:()D 35: pop2 36: invokestatic #23 // Method methodG:()V 39: invokestatic #24 // Method methodH:()V 42: new #14 // class edu/atlas/demo/java/jvm/SimpleMethodExecuteProcess 45: dup 46: invokespecial #15 // Method "<init>":()V 49: invokevirtual #25 // Method methodI:()V 52: invokestatic #26 // Method methodJ:()V 55: invokestatic #27 // Method methodK:()V 58: invokestatic #28 // Method methodL:()V 61: iload_2 62: ireturn LineNumberTable: line 128: 0 line 129: 4 line 130: 7 line 131: 25 line 132: 28 line 133: 32 line 134: 36 line 135: 39 line 136: 42 line 137: 52 line 138: 55 line 139: 58 line 140: 61