了解动态polymorphsim字节代码

时间:2018-04-07 20:11:18

标签: java polymorphism bytecode late-binding

我是Java字节代码的新手,想了解Dispatch.class的以下字节代码,相对于Dispatch.java源代码如下:

ForAllMaps((typeMap, mappingExpression) =>
{
    if (typeMap.DestinationType.GetProperty($"{typeMap.SourceType.Name}Id") != null)
    {
        mappingExpression.ForMember($"{typeMap.SourceType.Name}Id", o => o.MapFrom("Id"));
    }
});

在互联网上做了一些阅读后,我首先了解了JVM堆栈和操作码的工作原理。但是我仍然没有得到这些命令行的好处:

Compiled from "Dispatch.java"
class Dispatch {
  Dispatch();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class B
       3: dup
       4: invokespecial #3                  // Method B."<init>":()V
       7: astore_1
       8: aload_1
       9: invokevirtual #4                  // Method A.run:()V
      12: return
}

//=====================Dispatch.java==============================
class Dispatch{   
   public static void main(String args[]){
      A var = new B();  
      var.run(); // prints : This is B
   }
}
//======================A.java===========================
public class A {
    public void run(){
         System.out.println("This is A");
    }
}
//======================B.java===========================    
public class B extends A {
    public void run(){
          System.out.println("This is B");
    }
}

1 个答案:

答案 0 :(得分:0)

听起来你需要更多地阅读文档,但要回答你更新的问题,

  1. dup复制操作数堆栈的最高值。在这种情况下,它将是前一个B指令推送的未初始化的new对象。

  2. #3表示invokespecial正在类文件的常量池中的第3个插槽上运行。这是指定要调用的方法的位置。您可以通过将-c -verbose传递给javap来查看常量池。

  3. invokevirtual用于普通(非接口)虚方法调用。 (暂时忽略默认接口方法)invokespecial用于各种特殊情况 - 私有方法调用,构造函数调用和超类方法调用。