【问题标题】:Understanding dynamic polymorphsim byte code理解动态多态字节码
【发布时间】:2018-04-07 20:11:18
【问题描述】:

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

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");
    }
}

在网上阅读了一些资料后,我初步了解了 JVM 堆栈和操作码的工作原理。但是,我仍然不明白这些命令行有什么好处:

3: dup //what are we duplicating here exactly?
4: invokespecial #3 //what does the #3 in operand stand for?
invokevirtual VS invokespecial //what difference there is between these opcodes?

【问题讨论】:

标签: java polymorphism bytecode late-binding


【解决方案1】:

听起来您确实需要多阅读文档,但要回答您更新的问题,

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 2020-05-04
    相关资源
    最近更新 更多