invokevirtual,invokespecial,invokestatic,invokeinterface

 invokevirtual,invokespecial,invokestatic,invokeinterface

invokevirtual  调用类实例方法,方法引用 
        栈: 
        前:。。。,objectref,[arg1,[arg2......]] 
        后:。。。 
invlkestatic 调用类方法,不需要建新建类实例,此时操作数栈只要保存留参数即可 
        栈: 
        前:。。。,[arg1,[arg2.....]] 
        后:。。。 
invokespecial 使用对私有方法,超类方法和实例初始化方法的特殊处理来调用实例方法。 
        栈: 
        前:。。。,objectref,[arg1,[arg2......]] 
        后:。。。 
invokeinterface 调用接口方法 
        栈: 
        前:。。。,objectref,[arg1,[arg2......]] 
        后:。。。 



程序如下:

Java代码   收藏代码
  1. package yhs.test;  
  2.   
  3. public interface Iface {  
  4.     public void test();  
  5. }  
  6.   
  7. package yhs.test;  
  8.   
  9. public class Impl  
  10.   implements Iface {  
  11.   
  12.     public void test() {  
  13.     }  
  14.   
  15.     public static void testStatic() {  
  16.     }  
  17.   
  18.     private void testPrivate() {  
  19.     }  
  20.   
  21.     //--------------------------------------------------------------------------  
  22.     //--------------------------------------------------------------------------  
  23.     public static void main(String[] args) {  
  24.         Impl impl = new Impl();  
  25.         Iface iface = impl;  
  26.   
  27.         //热身  
  28.         int count = 10000000;  
  29.         for (int i = 0; i < count; i++) {  
  30.             impl.test();  
  31.             impl.testPrivate();  
  32.             Impl.testStatic();  
  33.             iface.test();  
  34.         }  
  35.   
  36.         //开始测试  
  37.         count = 100000000;  
  38.   
  39.         long t1 = System.currentTimeMillis();  
  40.         for (int i = 0; i < count; i++) {  
  41.             impl.test();  
  42.         }  
  43.         System.out.println("invokevirtual:   " +  
  44.                            (System.currentTimeMillis() - t1));  
  45.   
  46.         t1 = System.currentTimeMillis();  
  47.         for (int i = 0; i < count; i++) {  
  48.             impl.testPrivate();  
  49.         }  
  50.         System.out.println("invokespecial:   " +  
  51.                            (System.currentTimeMillis() - t1));  
  52.   
  53.         t1 = System.currentTimeMillis();  
  54.         for (int i = 0; i < count; i++) {  
  55.             Impl.testStatic();  
  56.         }  
  57.         System.out.println("invokestatic:    " +  
  58.                            (System.currentTimeMillis() - t1));  
  59.   
  60.         t1 = System.currentTimeMillis();  
  61.         for (int i = 0; i < count; i++) {  
  62.             iface.test();  
  63.         }  
  64.         System.out.println("invokeinterface: " +  
  65.                            (System.currentTimeMillis() - t1));  
  66.     }  
  67. }  
 



反汇编Impl.class产生的字节码如下:

public class yhs.test.Impl extends java.lang.Object implements yhs.test.Iface{
public yhs.test.Impl();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public void test();
  Code:
   0:   return

public static void testStatic();
  Code:
   0:   return

public static void main(java.lang.String[]);
  Code:
   0:   new     #2; //class Impl
   3:   dup
   4:   invokespecial   #3; //Method "":()V
   7:   astore_1
   8:   aload_1
   9:   astore_2
   //---------------------------------------------------------------------------------------------
   10:  ldc     #4; //int 10000000
   12:  istore_3
   13:  iconst_0
   14:  istore  4
   16:  goto    39
   19:  aload_1
   20:  invokevirtual   #5; //Method test:()V
   23:  aload_1
   24:  invokespecial   #6; //Method testPrivate:()V
   27:  invokestatic    #7; //Method testStatic:()V
   30:  aload_2
   31:  invokeinterface #8,  1; //InterfaceMethod yhs/test/Iface.test:()V
   36:  iinc    4, 1
   39:  iload   4
   41:  iload_3
   42:  if_icmplt       19
   //---------------------------------------------------------------------------------------------
   45:  ldc     #9; //int 100000000
   47:  istore_3
   48:  invokestatic    #10; //Method java/lang/System.currentTimeMillis:()J
   51:  lstore  5
   53:  iconst_0
   54:  istore  7
   56:  goto    66
   59:  aload_1
   60:  invokevirtual   #5; //Method test:()V
   63:  iinc    7, 1
   66:  iload   7
   68:  iload_3
   69:  if_icmplt       59
   72:  getstatic       #11; //Field java/lang/System.out:Ljava/io/PrintStream;
   75:  new     #12; //class StringBuffer
   78:  dup
   79:  invokespecial   #13; //Method java/lang/StringBuffer."":()V
   82:  ldc     #14; //String invokevirtual:
   84:  invokevirtual   #15; //Method java/lang/StringBuffer.append:(Ljava/lang/
String;)Ljava/lang/StringBuffer;
   87:  invokestatic    #10; //Method java/lang/System.currentTimeMillis:()J
   90:  lload   5
   92:  lsub
   93:  invokevirtual   #16; //Method java/lang/StringBuffer.append:(J)Ljava/lan
g/StringBuffer;
   96:  invokevirtual   #17; //Method java/lang/StringBuffer.toString:()Ljava/la
ng/String;
   99:  invokevirtual   #18; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
   //---------------------------------------------------------------------------------------------
   102: invokestatic    #10; //Method java/lang/System.currentTimeMillis:()J
   105: lstore  5
   107: iconst_0
   108: istore  8
   110: goto    120
   113: aload_1
   114: invokespecial   #6; //Method testPrivate:()V
   117: iinc    8, 1
   120: iload   8
   122: iload_3
   123: if_icmplt       113
   126: getstatic       #11; //Field java/lang/System.out:Ljava/io/PrintStream;
   129: new     #12; //class StringBuffer
   132: dup
   133: invokespecial   #13; //Method java/lang/StringBuffer."":()V
   136: ldc     #19; //String invokespecial:
   138: invokevirtual   #15; //Method java/lang/StringBuffer.append:(Ljava/lang/
String;)Ljava/lang/StringBuffer;
   141: invokestatic    #10; //Method java/lang/System.currentTimeMillis:()J
   144: lload   5
   146: lsub
   147: invokevirtual   #16; //Method java/lang/StringBuffer.append:(J)Ljava/lan
g/StringBuffer;
   150: invokevirtual   #17; //Method java/lang/StringBuffer.toString:()Ljava/la
ng/String;
   153: invokevirtual   #18; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
   //---------------------------------------------------------------------------------------------
   156: invokestatic    #10; //Method java/lang/System.currentTimeMillis:()J
   159: lstore  5
   161: iconst_0
   162: istore  9
   164: goto    173
   167: invokestatic    #7; //Method testStatic:()V
   170: iinc    9, 1
   173: iload   9
   175: iload_3
   176: if_icmplt       167
   179: getstatic       #11; //Field java/lang/System.out:Ljava/io/PrintStream;
   182: new     #12; //class StringBuffer
   185: dup
   186: invokespecial   #13; //Method java/lang/StringBuffer."":()V
   189: ldc     #20; //String invokestatic:
   191: invokevirtual   #15; //Method java/lang/StringBuffer.append:(Ljava/lang/
String;)Ljava/lang/StringBuffer;
   194: invokestatic    #10; //Method java/lang/System.currentTimeMillis:()J
   197: lload   5
   199: lsub
   200: invokevirtual   #16; //Method java/lang/StringBuffer.append:(J)Ljava/lan
g/StringBuffer;
   203: invokevirtual   #17; //Method java/lang/StringBuffer.toString:()Ljava/la
ng/String;
   206: invokevirtual   #18; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
   //---------------------------------------------------------------------------------------------
   209: invokestatic    #10; //Method java/lang/System.currentTimeMillis:()J
   212: lstore  5
   214: iconst_0
   215: istore  10
   217: goto    229
   220: aload_2
   221: invokeinterface #8,  1; //InterfaceMethod yhs/test/Iface.test:()V
   226: iinc    10, 1
   229: iload   10
   231: iload_3
   232: if_icmplt       220
   235: getstatic       #11; //Field java/lang/System.out:Ljava/io/PrintStream;
   238: new     #12; //class StringBuffer
   241: dup
   242: invokespecial   #13; //Method java/lang/StringBuffer."":()V
   245: ldc     #21; //String invokeinterface:
   247: invokevirtual   #15; //Method java/lang/StringBuffer.append:(Ljava/lang/
String;)Ljava/lang/StringBuffer;
   250: invokestatic    #10; //Method java/lang/System.currentTimeMillis:()J
   253: lload   5
   255: lsub
   256: invokevirtual   #16; //Method java/lang/StringBuffer.append:(J)Ljava/lan
g/StringBuffer;
   259: invokevirtual   #17; //Method java/lang/StringBuffer.toString:()Ljava/la
ng/String;
   262: invokevirtual   #18; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
   //---------------------------------------------------------------------------------------------
   265: return

}

测试得到类似如下的一组结果:

#1

invokevirtual:   250

invokespecial:   219

invokestatic:    125

invokeinterface: 1062

 

#2

invokevirtual:   281

invokespecial:   250

invokestatic:    141

invokeinterface: 1078
...
可以看出,静态方法调用最快,而通过接口调用方法最慢(比invokevirtual慢了3-4倍),调用private的方法比调用一般的方法稍快。

调用超类(在现在的jvm spec中与以前的有所不同,不是通过invokespecial来调用)的方法不是很好测试,再想想看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Java程序的转换,需要进行以下步骤: 1. 将Java代码转换为汇编代码,使用Java虚拟机(JVM)来执行Java程序,然后将其转换为汇编代码。 2. 根据汇编代码的语法规则,将其转换为MASM汇编代码。 下面是Test.java转换为汇编代码的示例: ``` .class public Test .super java/lang/Object .field public static final KEY:I = 7 .method public static main([Ljava/lang/String;)V .limit stack 2 .limit locals 3 ldc "Hello World!" astore_1 new java/lang/StringBuffer dup invokespecial java/lang/StringBuffer/<init>()V astore_2 new java/lang/StringBuffer dup invokespecial java/lang/StringBuffer/<init>()V astore_3 iconst_0 istore 4 loop: iload 4 aload_1 invokevirtual java/lang/String/length()I if_icmpge end_loop aload_1 iload 4 invokevirtual java/lang/String/charAt(I)C iload_0 ixor i2c invokevirtual java/lang/StringBuffer/append(C)Ljava/lang/StringBuffer; pop iinc 4, 1 goto loop end_loop: iconst_0 istore 4 loop2: iload 4 aload_2 invokevirtual java/lang/StringBuffer/length()I if_icmpge end_loop2 aload_2 iload 4 invokevirtual java/lang/StringBuffer/charAt(I)C iload_0 ixor i2c invokevirtual java/lang/StringBuffer/append(C)Ljava/lang/StringBuffer; pop iinc 4, 1 goto loop2 end_loop2: getstatic java/lang/System/out Ljava/io/PrintStream; ldc "原始的字符串为:" invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V aload_1 invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V getstatic java/lang/System/out Ljava/io/PrintStream; ldc "加密后的字符串为:" invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V aload_2 invokevirtual java/lang/StringBuffer/toString()Ljava/lang/String; invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V getstatic java/lang/System/out Ljava/io/PrintStream; ldc "解密后的字符串为:" invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V aload_3 invokevirtual java/lang/StringBuffer/toString()Ljava/lang/String; invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V return .end method ``` 下面是将上述汇编代码转换为MASM汇编代码的示例: ``` DATAS SEGMENT DATAS ENDS STACKS SEGMENT DW 64 DUP(?) STACKS ENDS CODES SEGMENT ASSUME CS:CODES,DS:DATAS,SS:STACKS START: MOV AX,DATAS MOV DS,AX ; 初始化局部变量 MOV CX,0 ; i=0 MOV DX,0 ; 存储加密后的字符串的下标 MOV BX,0 ; 存储解密后的字符串的下标 ; 加密过程 loop1: MOV AX,CX PUSH AX MOV AX,DATAS+1 PUSH AX CALL java/lang/String/length ADD SP,4 CMP AX,CX JLE end_loop1 MOV AX,CX PUSH AX MOV AX,1 PUSH AX MOV AX,DATAS+3 MOV BX,DX ADD AX,BX MOVZX BX,WORD PTR [AX] MOV AX,DATAS+2 MOV CX,7 XOR BX,CX MOV CX,BX MOV AX,DATAS+5 MOV BX,DX ADD AX,BX MOV BYTE PTR [AX],CL INC DX ADD SP,4 JMP loop1 end_loop1: MOV CX,0 MOV BX,0 ; 解密过程 loop2: MOV AX,CX PUSH AX MOV AX,DATAS+1 PUSH AX CALL java/lang/StringBuffer/length ADD SP,4 CMP AX,CX JLE end_loop2 MOV AX,CX PUSH AX MOV AX,1 PUSH AX MOV AX,DATAS+7 MOV BX,BX ADD AX,BX MOVZX BX,WORD PTR [AX] MOV AX,DATAS+6 MOV CX,7 XOR BX,CX MOV CX,BX MOV AX,DATAS+9 MOV BX,BX ADD AX,BX MOV BYTE PTR [AX],CL INC BX ADD SP,4 JMP loop2 end_loop2: ; 输出结果 MOV DX,OFFSET FLAT:DATAS+10 MOV AH,9 INT 21h MOV DX,DATAS+1 MOV AH,9 INT 21h MOV DX,OFFSET FLAT:DATAS+11 MOV AH,9 INT 21h MOV DX,DATAS+7 MOV AH,9 INT 21h MOV DX,DATAS+12 MOV AH,9 INT 21h MOV DX,DATAS+7 MOV AH,9 INT 21h MOV DX,DATAS+13 MOV AH,9 INT 21h MOV DX,DATAS+7 MOV AH,9 INT 21h MOV DX,DATAS+14 MOV AH,9 INT 21h MOV AX,4C00h INT 21h CODES ENDS END START ``` 请注意,这只是一个示例代码,需要根据具体情况进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值