千家信息网

Java中怎么调用字节码

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,本篇文章为大家展示了Java中怎么调用字节码,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。实例源码实例共两个java文件,一个是接口另一个是类,先看接口源码,
千家信息网最后更新 2026年10月31日Java中怎么调用字节码

本篇文章为大家展示了Java中怎么调用字节码,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

实例源码

实例共两个java文件,一个是接口另一个是类,先看接口源码,很简单只有一个方法声明:

package com.bolingcavalry;public interface Action {    void doAction();}

接下来的类实现了这个接口,而且还有自己的共有、私有、静态方法:

package com.bolingcavalry;public class Test001 implements Action{    private int add(int a, int b){        return a+b;    }    public String getValue(int a, int b){        return String.valueOf(add(a,b));    }    public static void output(String str){        System.out.println(str);    }    @Override    public void doAction() {        System.out.println("123");    }    public static void main(String[] args){        Test001 t = new Test001();        Action a = t;        String str = t.getValue(1,2);        t.output(str);        t.doAction();        a.doAction();    }                public void createThread(){        Runnable r = () -> System.out.println("123");    }}

小结一下,Test001的代码中主要的方法如下:

  1. 一个私有方法add;

  2. 一个公有方法getValue,里面调用了add方法;

  3. 一个静态方法output;

  4. 实现接口定义的doAction;

  5. 一个公有方法,里面使用了lambda表达式;

  6. main方法中,创建对象,调用getValue,output,doAction;

接下来我们通过javac命令或者ide工具得到Action.class和Test001.class文件,如果是用Intellij IDEA,可以先把Test001运行一遍,然后在工程目录下找到out文件夹,打开后里面是production文件夹,再进去就能找到对应的package和class文件了,如下图:

打开命令行,在Test001.class目录下执行javap -c Test001.class ,就可以对class文件进行反汇编,得到结果如下:

Compiled from "Test001.java"public class com.bolingcavalry.Test001 implements com.bolingcavalry.Action {  public com.bolingcavalry.Test001();    Code:       0: aload_0       1: invokespecial #1                  // Method java/lang/Object."":()V       4: return  public java.lang.String getValue(int, int);    Code:       0: aload_0       1: iload_1       2: iload_2       3: invokespecial #2                  // Method add:(II)I       6: invokestatic  #3                  // Method java/lang/String.valueOf:(I)Ljava/lang/String;       9: areturn  public static void output(java.lang.String);    Code:       0: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;       3: aload_0       4: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V       7: return  public void doAction();    Code:       0: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;       3: ldc           #6                  // String 123       5: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V       8: return  public static void main(java.lang.String[]);    Code:       0: new           #7                  // class com/bolingcavalry/Test001       3: dup       4: invokespecial #8                  // Method "":()V       7: astore_1       8: aload_1       9: astore_2      10: aload_1      11: iconst_1      12: iconst_2      13: invokevirtual #9                  // Method getValue:(II)Ljava/lang/String;      16: astore_3      17: aload_1      18: pop      19: aload_3      20: invokestatic  #10                 // Method output:(Ljava/lang/String;)V      23: aload_1      24: invokevirtual #11                 // Method doAction:()V      27: aload_2      28: invokeinterface #12,  1           // InterfaceMethod com/bolingcavalry/Action.doAction:()V      33: returnpublic void createThread();    Code:       0: invokedynamic #13,  0             // InvokeDynamic #0:run:()Ljava/lang/Runnable;       5: astore_1       6: return}

现在我们可以对比反汇编结果来学习字节码的用法了:

invokespecial:调用私有实例方法

getValue()方法中调用了私有实例方法add(int a, int b),反编译结果如下所示,注意编号为3的那一行:

public java.lang.String getValue(int, int);    Code:       0: aload_0       1: iload_1       2: iload_2       3: invokespecial #2                  // Method add:(II)I       6: invokestatic  #3                  // Method java/lang/String.valueOf:(I)Ljava/lang/String;       9: areturn

可见私有实例方法的调用是通过invokespecial指令来实现的;

invokestatic:调用静态方法

getValue()方法中,调用了静态方法String.valueOf(),反编译结果如下所示,注意编号为6的那一行:

public java.lang.String getValue(int, int);    Code:       0: aload_0       1: iload_1       2: iload_2       3: invokespecial #2                  // Method add:(II)I       6: invokestatic  #3                  // Method java/lang/String.valueOf:(I)Ljava/lang/String;       9: areturn

可见静态方法的调用是通过invokestatic指令来实现的;

invokevirtual:调用实例方法

在main()方法中,调用了t.getValue(1,2)方法,反编译结果如下所示,注意编号为13的那一行:

public static void main(java.lang.String[]);    Code:       0: new           #7                  // class com/bolingcavalry/Test001       3: dup       4: invokespecial #8                  // Method "":()V       7: astore_1       8: aload_1       9: astore_2      10: aload_1      11: iconst_1      12: iconst_2      13: invokevirtual #9                  // Method getValue:(II)Ljava/lang/String;      16: astore_3      17: aload_1      18: pop      19: aload_3      20: invokestatic  #10                 // Method output:(Ljava/lang/String;)V      23: aload_1      24: invokevirtual #11                 // Method doAction:()V      27: aload_2      28: invokeinterface #12,  1           // InterfaceMethod com/bolingcavalry/Action.doAction:()V      33: return}

可见调用一个实例的方法的时候,通过invokevirtual指令来实现的;

invokeinterface:调用接口方法

在main()方法中,我们声明了接口Action a,然后调用了a.doAction(),反编译结果如下所示,注意编号为28的那一行:

public static void main(java.lang.String[]);    Code:       0: new           #7                  // class com/bolingcavalry/Test001       3: dup       4: invokespecial #8                  // Method "":()V       7: astore_1       8: aload_1       9: astore_2      10: aload_1      11: iconst_1      12: iconst_2      13: invokevirtual #9                  // Method getValue:(II)Ljava/lang/String;      16: astore_3      17: aload_1      18: pop      19: aload_3      20: invokestatic  #10                 // Method output:(Ljava/lang/String;)V      23: aload_1      24: invokevirtual #11                 // Method doAction:()V      27: aload_2      28: invokeinterface #12,  1           // InterfaceMethod com/bolingcavalry/Action.doAction:()V      33: return}

可见调用一个接口的方法是通过invokeinterface指令来实现的; 其实t.doAction()和a.doAction()最终都是调用Test001的实例的doAction,但是t的声明是类,a的声明是接口,所以两者的调用指令是不同的;

invokedynamic:调用动态方法

在main()方法中,我们声明了一个lambda() -> System.out.println("123"),反编译的结果如下:

 0: invokedynamic #13,  0             // InvokeDynamic #0:run:()Ljava/lang/Runnable;       5: astore_1       6: return

可见lambda表达式对应的实际上是一个invokedynamic调用,具体的调用内容,可以用Bytecode viewer这个工具来打开Test001.class再研究,由于反编译后得到invokedynamic的操作数是#13,我们先去常量池看看13对应的内容:

是个Name and type和Bootstrap method,再细看Bootstrap method的操作数,如下图:

是个MethodHandler的引用,指向了用户实现的lambda方法;

上述内容就是Java中怎么调用字节码,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

方法 实例 接口 结果 文件 编译 指令 静态 私有 一行 内容 字节 接下来 命令 工具 技能 操作数 文件夹 源码 目录 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州百单互联网科技有限公司 国智互联网科技 万易互联网科技 南京欣网互联网科技 哈尔滨新华互联网科技 四个字互联网科技公司取名 老年人脱离互联网科技的作文 深圳育鹏互联网科技有限公司招聘 互联网行业科技股 互联网科技创新的路径 阿里互联网科技企业 玉溪新华互联网科技好不好 南博望互联网科技有限公司 恒生互联网科技业指数调整周期 浙南科技城互联网大厦招聘 从那以后互联网科技有限公司 有人说阿里系是互联网科技企业 互联网硬科技公司 同城互联网络科技 小牛互联网科技有限公司地址 新华互联网科技学校 互联网科技ppt模板 互联网科技股有哪些 老年人脱离互联网科技的作文 互联网软件和科技 江阴互联网智能科技产品进口 中国互联网有什么科技 广州燕处互联网科技有限公司 互联网科技博主张洲 保山浩联互联网科技有限公司
0