java - 为什么 JVM 无法检测到缺失的方法实现?

标签 java

我们有一个应用程序,我们分别在其中发布和接口(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)的实现。它做什么并不重要。 下一步是一些技巧。

  1. 我编译 v1 目录中的文件。
  2. 我将文件从 v2 复制到 mix 目录,以便可以编译 Mix.java
  3. 无论是否设置了“foo”属性,程序都可以运行。
  4. 我将 DummyImpl.class 从 v1 目录复制到 mix 目录。
  5. 我运行该程序。它有效。

v1 实现显然不满足 v2 接口(interface),但 JVM 会很乐意允许我运行该程序。

如果我设置“foo”属性,它将失败,但直到我真正到达代码中的该行。

我想这就是我的问题所在:这是有保证的行为吗?如果是这样,在哪里指定在这种情况下将会/应该发生什么?

我的例子当然很愚蠢,但由于我们在一个更大的系统中也有类似的情况,我想知道我们可以指望什么起作用,什么不起作用,以及我们无法知道什么”会工作的。

最佳答案

编译器会为您的调用生成一个invokeinterface字节码(而不是invokespecial)。该字节码对运行时调用的具体方法进行多步查找。因此您的代码在编译时不会失败。

关于java - 为什么 JVM 无法检测到缺失的方法实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32459695/

相关文章:

java - 为什么 Eclipse 引用 1.4 JRE?

java - 正则表达式拆分成重叠的字符串

java - 请求中的 GAE 错误代码 104 破坏了所有并发请求

java - 正则表达式匹配用多个逗号分隔的数字

java - java直接发送音频到扬声器

java - 无法使用 Castor 映射工具

java - Maven Mojos 中的注释与 Javadoc

java - 为什么文件没有删除?输入/输出

java - @KafkaListener 每天消费一百万多条消息的更好解决方案?

java - 在字符串上调用替换会抛出 EvaluatorException