DEX 和 Dalvik 是否支持 Java 二进制兼容性?

Do DEX and Dalvik support Java binary compatibility?

我正在构建一个基于 Android 的系统,该系统需要通过二进制协议发送数据。我预计会有多个协议的多个版本以及维护它们所带来的噩梦。

我突然想到,通过使用 Java 的二进制兼容性,我或许可以回避大部分版本控制问题。

假设应用程序 A 依赖库 LL 包含 class C,用于 A,实现了接口 I。我使用接口 I 的定义 I(0) 构建了 LA。我在设备上安装 L(0)A(0)A(0) 动态绑定 L(0) 提供 class C(0).

现在,我扩展接口 I,例如添加两个新方法。当我尝试编译 L 时,编译失败,因为 C 没有实现新方法。我通过扩展 C 修复了 L,因此它实现了两个新方法。我现在针对 I(1) 编译 L(1) 并将其安装在设备上。

请注意,此时 A 不会针对 I(1) 进行编译。 None 越少,如果这是 Java,A(0) 将绑定和 运行,正确地,使用 L(1) 中的 C(1)

对于 Java 的实现,JLS 第 13 章二进制兼容性保证了此行为(以及更多)。如果它适用于 DEX 和 Dalvik,那么我可以让大量 class 的协议更改对他们的客户完全不可见。

所以,问题是,DEX 和 Dalvik 是否遵守 JLS 二进制兼容性规范?如果没有,是否有指定 DEX/Dalvik 二进制兼容性的文档?

我不能权威地谈论 Dalvik VM(或相关运行时,如 ART)的当前发布版本,但作为 .dex 格式的设计者,我 可以 说出意图:

我不会声称我严格遵守 .dex 格式设计中的任何规范。我要说的是,我希望该格式成为一个合适的容器,用于表示最初用 Java 编程语言编写的程序,包括对独立代码编译和演化环境中的跨代码兼容性的担忧.

也就是说(正如我暗示的那样)这是一个实施领域,超级容易出错,并且在实践中经常会长时间未被发现的问题正是因为很少有程序真正依赖于您感兴趣的保证类型。

所以,我的意图可能并不重要,重要的是世界上的 VM 实际做了什么。我强烈建议在野外的几个不同 VM 上显式测试各种交叉链接和升级方案。根据您设计中的此功能,您可能会发现结果不尽如人意。