从字节码角度理解静态方法和实例方法的调用

8 篇文章 0 订阅

微信公众号:Java 知其所以然
关注可了解更多的教程。问题或建议,请公众号留言;

实例方法的调用

代码

public class App {
    public static void main(String[] args{
        App a = (App) null;
        System.out.println(a);
        a.test();
    }
    public void test(){
        System.out.println("do something");
    }
}

结果很明显,会报空指针异常。

分析字节码

主要来看这条语句

a.test()

它对应的字节码为

aload_1    // 加载局部变量表 1 号位的数据,也就是把引用 a 压栈
invokevirtual #5  // 执行实例方法,也就是执行 test() 方法

我们可以看出,当执行实例方法时,需要先将对象的引用压入操作数栈中,然后弹出栈去执行实例方法。

静态方法的调用

代码

public class App {
    public static void main(String[] args{
        App a = (App) null;
        System.out.println(a);
        a.test();
    }
    public static void test(){
        System.out.println("do something");
    }
}

结果
do something

分析字节码

主要来看这条语句

a.test()

它对应的字节码为

aload_1   // 加载局部变量表 1 号位的数据,也就是把引用 a 压栈
pop  // 弹出栈堆第一个元素,也就是弹出引用 a
invokestatic #5  // 调用执行静态方法 test()

我们可以看出,当执行静态方法时,先将对象的引用压入操作数栈中,然后又弹出栈去了,仅需要 invokestatic 这条指令执行静态方法就可以。

思考

引用 a 压入又弹出,说明执行 invokestatic 这条指令根本就不需要依赖引用 a 这个数据。从而说名了静态方法的调用依赖的是类对象( App.class )。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值