classFile access_flag ACC_SUPER

ACC_SUPER 这个标志是为了纠正 invokespecial 在调用父类方法存在的版本问题。invokespecial是一个调用方法的字节码指令,用在调用构造方法、本类private方法、父类非虚方法3种场景(有一点要注意的是,JDK1.1之前,invokespecial 调用指定方法)它调用指定前两个调用没有问题,在调用父类方法时,存在版本的问题:
组建A,版本1:
public class GrandParent {
  protected void myMethod() {
    // ...
  }
}
public class Parent extends GrandParent {
}
调用方B,版本1:
public class Child extends Parent {
  protected void myMethod() {
    // ...
    super.myMethod();
  }
}
版本1中的调用方调用super.myMethod()时,由于调用指定的方法,会调到GrandParent.myMethod(),这时没有问题
作者修改了组建A:
public class GrandParent {
  protected void myMethod() {
    // ...
  }
}
public class Parent extends GrandParent {
  protected void myMethod() {
    // ...
    super.myMethod();
  }
}
这时调用方,在没有重新编译的情况下,仍然会调用到GrandParent.myMethod(),这显然不符合作者的预期。
JDK1.1之前,invokespecial 调用指定方法,1.1中变成了搜索父类的最近的方法,但前提是设置了 ACC_SUPER 标志位,如果设置了ACC_SUPER,这时调用方,在没有重新编译的情况下,会搜索到Parent.myMethod(),这个问题得到了解决。

详见:
http://weblog.ikvm.net/PermaLink.aspx?guid=99fcff6c-8ab7-4358-9467-ddf71dd20acd

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值