我们有一个应用程序,我们分别在其中发布和接口(interface)以及实现。用户将根据我们的接口(interface)进行编译,但只有在运行时他们才需要部署实现。从未明确提及实现。
我有点好奇如果混合接口(interface)和实现的版本会发生什么(例如,新版本会添加方法)。所以,我做了一个简单的例子:
├── mix
│ └── Mix.java
├── v1
│ ├── DummyImpl.java
│ └── DummyInterface.java
└── v2
├── DummyImpl.java
└── DummyInterface.java
v1 的界面如下所示:
interface DummyInterface {
void v1();
}
v2 的界面如下所示:
interface DummyInterface {
void v1();
void v2();
}
Mix.java 文件如下所示:
class Mix {
public static void main(String[] args) {
DummyInterface di = new DummyImpl();
di.v1();
if (System.getProperty("foo") != null)
di.v2();
}
}
*Impl 类包含某种接口(interface)的实现。它做什么并不重要。 下一步是一些技巧。
- 我编译 v1 目录中的文件。
- 我将文件从 v2 复制到 mix 目录,以便可以编译 Mix.java
- 无论是否设置了“foo”属性,程序都可以运行。
- 我将 DummyImpl.class 从 v1 目录复制到 mix 目录。
- 我运行该程序。它有效。
v1 实现显然不满足 v2 接口(interface),但 JVM 会很乐意允许我运行该程序。
如果我设置“foo”属性,它将失败,但直到我真正到达代码中的该行。
我想这就是我的问题所在:这是有保证的行为吗?如果是这样,在哪里指定在这种情况下将会/应该发生什么?
我的例子当然很愚蠢,但由于我们在一个更大的系统中也有类似的情况,我想知道我们可以指望什么起作用,什么不起作用,以及我们无法知道什么”会工作的。
最佳答案
编译器会为您的调用生成一个invokeinterface
字节码(而不是invokespecial
)。该字节码对运行时调用的具体方法进行多步查找。因此您的代码在编译时不会失败。
关于java - 为什么 JVM 无法检测到缺失的方法实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32459695/