java编程

java动态绑定以及invokespecial指令

字号+ 作者:zhuawa 来源:未知 2017-06-19 14:57 我要评论( )

下面介绍一个invokespecial指令,注意,黑色粗体的操作栈 是指jvm执行该指令时,当前的jvm操作栈状态 invokespecial 指令详解 操作: 调用实例方法;专门为父类,私有方法,以及实例方法处理 格式: invokespecial indexbyte1 indexbyte2 编号 invokespecial =

java多态,是指方法可以重载、子类重写父类的protected以及public方法。这些全都离不开一个一个叫动态绑定的东西。
动态绑定只是jvm在运行时会根据运行时的数据去执行相关操作,确切的说调用对象的方法或者对对象赋值的时候,jvm会根据实际对象来执行这个操作。
静态绑定静态方法不存在动态绑定,指令使用的是invokestatic,并且解析常亮池的方法引用的时候是根据引用类型去解析的,如果是Father型引用,就是Father的setName,如果是Son型引用就是Son的setName
这里做研究的是Father  、Son;Son 继承Father,其中有两个属性,一个是实例属性 age,一个是类属性 name。两者分别用父类指向子类的方式去执行,
结果会是咋样?呵呵,当然结果在注释中已经说出来了

代码如下:
public class Father
{
    public Long age;
    
    public static String name;
    
    public static void main(String[] args){
        Father fa=new Father();
        fa.age=10L;
        Father fa2=new Son();
        fa2.age=30L;
        fa.setName("son");
        fa2.setName("father");

        System.out.println(Father.name);//father
        System.out.println(Son.name);//null
        System.out.println(fa.name);//father
        System.out.println(fa2.name);//father
        System.out.println(fa.age);//10L
        System.out.println(fa2.age);//30L
        
    }

    public static void setName(String name){
        Father.name=name;
    }
}

class Son extends Father{
    public Long age;
    
    public static String name;
    
    public static void setName(String name){
        Son.name=name;
    }
}

那是什么原因呢?
我们从jvm的指令执行的角度去定位。

javap -p -v -version -l -c -s -sysinfo Father.class  去显示jvm执行的指令,其中关键部分如下:

这是创建Father对象,并对Father对象的age赋值。putfield是对实例的赋值,在putfield之前执行了aload_1这条,意思就是将需要赋值的实例对象放入栈里,给putfield 使用,而这个对象就是Father的实例对象,存在局部变量表 index=1的位置
         0: new           #2                  // class Father
         3: dup           
         4: invokespecial #3                  // Method "<init>":()V
         7: astore_1      
         8: aload_1       
         9: ldc2_w        #4                  // long 10l
        12: invokestatic  #6                  // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
        15: putfield      #7                  // Field age:Ljava/lang/Long;
这是创建son对象,并对son对象的age赋值;其中这里就用到了动态绑定,虽然是Father类型的引用但aload_2 是index=2位置的实例。也即是Son实例化的对象,实际上是对Son的age赋值。
       18: new           #8                  // class Son
        21: dup           
        22: invokespecial #9                  // Method Son."<init>":()V
        25: astore_2      
        26: aload_2       
        27: ldc2_w        #10                 // long 30l
        30: invokestatic  #6                  // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
        33: putfield      #7                  // Field age:Ljava/lang/Long;

而这里是虽然aload_1 但又pop了,而且invokestatic指令和当前实例无关,最后调用的就是Father的setName。
    这是     fa.setName("son");这句的执行
       36: aload_1       
        37: pop           
        38: ldc           #12                 // String son
        40: invokestatic  #13                 // Method setName:(Ljava/lang/String;)V
    这是 fa2.setName("father");这句的执行;而这里是虽然aload_2 也pop了,而且invokestatic指令和当前实例无关,最后调用的就是Father的setName
        43: aload_2       
        44: pop           
        45: ldc           #14                 // String father
        47: invokestatic  #13                 // Method setName:(Ljava/lang/String;)V



下面介绍一个invokespecial指令,注意,黑色粗体的“操作栈”是指jvm执行该指令时,当前的jvm操作栈状态,objectref 指当前指令所属的操作实例
invokespecial 指令详解

操作:
调用实例方法;专门为父类,私有方法,以及实例方法处理

格式:


invokespecial
indexbyte1
indexbyte2

编号

invokespecial = 183 (0xb7)

操作栈

..., objectref, [arg1, [arg2 ...]] →  //非实例化方法的时候

...  //调实例化方法的时候,操作栈就是这种情况



使用例子:
        18: new           #8                  // class Son
        21: dup           
        22: invokespecial #9                  // Method Son."<init>":()V
        25: astore_2      
        26: aload_2      
这里为什么要dup呢,dup是将栈顶数值复制一份并送入至栈顶。因为invokespecial会消耗掉一个Son型引用,因而需要复制一份。


这是oracle官网的指令集,以后方便查阅
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html

转载请注明出处。

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • java LinkedList数据结构

    java LinkedList数据结构

    2017-03-30 15:33

  • Jvm虚拟机学习一些基本概念

    Jvm虚拟机学习一些基本概念

    2017-05-18 11:12

  • java的class文件查看(入门)

    java的class文件查看(入门)

    2016-09-22 16:36

  • java class文件结构

    java class文件结构

    2016-08-10 17:29

网友点评
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)