gpt4 book ai didi

Java 二进制兼容性 - RFC 关于使用 invokevirtual 语义的协变返回类型的建议解决方案

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:40:36 25 4
gpt4 key购买 nike

我正在尝试改进 API。作为这种演变的一部分,我需要将方法的返回类型更改为子类(专门化),以便高级客户端能够访问新功能。示例(忽略丑陋的:

public interface Entity {
boolean a();
}

public interface Intf1 {
Entity entity();
}

public interface Main {
Intf1 intf();
}

我现在想要这样的 ExtendedEntity、Intf2 和 Main:

public interface ExtendedEntity extends Entity {
boolean b();
}

public interface Intf2 extends Intf1 {
ExtendedEntity entity();
}

public interface Main {
Intf2 intf();
}

但是,由于方法返回类型是其签名的一部分,因此使用以前版本的代码编译的客户端显示链接错误(未找到方法 iirc)。

我想做的是向 Main 添加一个具有不同返回类型的方法。这两种方法(一种返回父类(super class)型,另一种返回子类型)应该映射到相同的实现方法(返回子类型)。注意 - 据我所知,这是 JVM 允许的,但 Java 规范不允许。

我的解决方案似乎滥用(对此我没有其他说法)Java 类系统来添加所需的接口(interface)。

public interface Main_Backward_Compatible {
Intf1 intf();
}

public interface Main extends Main_Backward_Compatible{
Intf2 intf();
}

现在,旧客户端会将正确的方法返回给 invokevirtual 查找(因为具有正确返回类型的方法存在于类型层次结构中)并且实际工作的实现将是返回子类型 Intf2 的实现。

似乎有效。在我能设计的所有测试中(除了反射 - 但我不关心那一点)它确实有效。
它会一直有效吗?我的推理(关于 invokevirtual)是否正确?

另一个相关的问题 - 有没有工具可以检查“真正的”二进制兼容性?我发现的唯一方法是单独查看每个方法,但没有考虑类型层次结构。

谢谢,
跑了。

编辑 - 我尝试过但发现“不太好”的工具(不考虑类型层次结构):

  1. Clirr 0.6。
  2. IntelliJ“APIComparator”插件。

Edit2 - 当然,我的客户被禁止为我的接口(interface)创建实现类(想想服务)。但是,如果您希望示例完整,请考虑使用抽象类(对于 Main)而不是接口(interface)。

最佳答案

这篇文章足够长,我承认我没有仔细阅读所有内容,但看起来您可能真的想在这里利用泛型。如果你输入 Intf1 我认为你可以在引入特化的同时保持二进制兼容性:

public interface Intf1<T extends Entity> {
T entity(); //erasure is still Entity so binary compatibility
}

public interface Intf2 extends Intf1<ExtendedEntity> { //if even needed
}

public interface Main {
Intf1<ExtendedEntity> intf(); //erasure is still Intf1, the raw type
}

编辑 #1: 在尝试保持二进制兼容性时有一些注意事项。查看Generics Tutorial第 6 章和第 10 章了解更多信息。

编辑#2:

您也可以将此概念扩展到键入 Main:

public interface Main<T, I extends Intf1<T>> {
I intf(); //still has the same erasure as it used to, so binary compatible
}

然后,老客户将能够像过去一样使用原始 Main 类型,而无需重新编译,新客户将键入对 Main 的引用:

Main<ExtendedEntity, Intf2> myMain = Factory.getMeAMain();
Intf2 intf = myMain.intf();

关于Java 二进制兼容性 - RFC 关于使用 invokevirtual 语义的协变返回类型的建议解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3499981/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com