首页 > 解决方案 > 为什么 invokevirtual 的目标类型从 javac 目标 1.1 更改为 1.2?

问题描述

我知道这些是古老的 Java 版本,但我仍然很好奇。给定以下代码段:

public void test(java.awt.event.MouseEvent e)
{
    System.out.println(e.getID());
}

使用它编译时javac -source 1.3 -target 1.1会生成以下内容:

public void test(java.awt.event.MouseEvent);
 Code:
   0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
   3: aload_1       
   4: invokevirtual #3                  // Method java/awt/AWTEvent.getID:()I
   7: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
  10: return 

使用它编译时javac -source 1.3 -target 1.2会生成以下内容:

public void test(java.awt.event.MouseEvent);
 Code:
   0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
   3: aload_1       
   4: invokevirtual #3                  // Method java/awt/event/MouseEvent.getID:()I
   7: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
  10: return

为什么 invokevirtual 的目标类型(参见第 4 行)从目标 1.1 更改为目标 1.2 ?

标签: javajavac

解决方案


经过一些研究,看起来这种更改是从 Java 1.2 开始在 javac 中引入的,以符合 JLS 二进制兼容性规则。以下引用直接来自javac 源代码

从 -target 1.2 开始,我们遵循 JLS 二进制兼容性规则,将限定符的类型作为对方法或字段的引用的限定类型发出。在早期的目标中,我们使用在其中找到成员的类作为限定类型。


推荐阅读