小编Сер*_*еев的帖子

使用静态方法将类更改为Java中的接口的二进制兼容性

我遇到了以下奇怪的Java/JVM规范不完整的情况.假设我们有类(我们将使用Java 1.8和HotSpot):

public class Class {
  public static void foo() {
    System.out.println("hi");
  }
}

public class User {
  public static void main(String[] args) {
    Class.foo();
  }
}
Run Code Online (Sandbox Code Playgroud)

然后重新编译Class to be an interface without recompiling theUser`:

public interface Class {
  public static void foo() {
    System.out.println("hi");
  }
}
Run Code Online (Sandbox Code Playgroud)

运行User.mainnow会产生相同的输出hi.这似乎是显而易见的,但我希望它会失败,IncompatibleClassChangeError这就是为什么:

我知道根据JVM 5.3.5#3语句将类更改为接口是二进制不兼容:

如果命名为C的直接超类的类或接口实际上是一个接口,则加载会抛出一个IncompatibleClassChangeError.

但是我们假设我们没有继承者Class.我们现在必须参考JVM规范来了解方法的分辨率.第一个版本被编译成这个字节码:

public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #2                  // Method examples/Class.foo:()V
       3: return
Run Code Online (Sandbox Code Playgroud)

所以我们这里有一个叫做 …

java jvm language-specifications binary-compatibility

5
推荐指数
1
解决办法
372
查看次数