捕获 Java 中的转换问题、JLS 的 WRT 协调和实际 JDK 行为
给定以下两个类定义:
class C1<T extends C1<T>> {}
class C2<U> extends C1<C2<U>> {}
请考虑以下类型声明:
C1<? extends C2<String>> c;
这在 JDK-8u45 中编译得很好,但是如果我们检查捕获转换的规范,似乎(在我看来)此声明应该会导致编译时错误。
特别是,新类型变量捕获的上限由 给出,在这种情况下解析为通配符绑定并解析为 。T#1
glb(Bi, Ui[A1:=S1,...,An:=Sn])
Bi
C2<String>
Ui[A1:=S1,...,An:=Sn]
C1<T#1>
由此,解析为交集类型 ,这是无效的,因为 和 都是类类型,而不是接口类型,但它们都不是另一个的子类型。glb(C2<?>, C1<T#1>)
C2<String> & C1<T#1>
C2<String>
C1<T#1>
这种(明显的)规则违规可能在交叉点类型本身的定义中更加清晰。
我相信这不是一个错误,我只是在某个地方犯了一些简单的错误......如果它是一个错误,我希望它可以被认为是JLS中的错误,而不是JDK中的错误,这样我就可以期望能够安全地模拟行为......
感谢您的任何帮助!
编辑:在昨天与Radiodef交谈后,我说服了自己,这个问题(或者至少是看待它的一种方式)是可以有效地被认为是的子类型,因为T#1只能被满足,因此可以被认为是相等的,但是包含和子类型规则不理解这种关系, 因此,JLS将无法识别子类型,并且应该失败...C2<String>
C1<T#1>
C2<String>
但是,如果您采用 稍微复杂一些的情况,则更棘手。问题是相似的,但是在捕获上形成上限的交集类型显示为 ,其中似乎没有解决方案可以通过与上述相同的推理得出。C1<? extends C2<?>> d;
C2<?> & C1<T#2>