捕获 Java 中的转换问题、JLS 的 WRT 协调和实际 JDK 行为 [英] Capture conversion issue in Java, WRT reconciliation of JLS and actual JDK behaviour

查看:31
本文介绍了捕获 Java 中的转换问题、JLS 的 WRT 协调和实际 JDK 行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下两个类定义:

class C1<T extends C1<T>> {}

class C2<U> extends C1<C2<U>> {}

考虑以下类型声明:

C1<? extends C2<String>> c;

这在 JDK-8u45 中编译得很好,但是如果我们检查 捕获转换规范,看来(对我来说)这个声明应该导致编译时错误.

This compiles fine in JDK-8u45, but if we examine the specification for capture conversion, it appears (to me) that this declaration should result in a compile time error.

特别是新类型变量捕获T#1的上限由glb(Bi, Ui[A1:=S1,...,An:=Sn]),在这种情况下 Bi 解析为通配符绑定 C2Ui[A1:=S1,...,An:=Sn] 解析为 C1.

In particular, the upper bound of the new type variable capture T#1 is given by glb(Bi, Ui[A1:=S1,...,An:=Sn]), where in this case Bi resolves to the wildcard bound C2<String> and Ui[A1:=S1,...,An:=Sn] resolves to C1<T#1>.

由此,glb(C2, C1) 解析为交集类型C2;&C1,无效,因为C2C1都是类类型,不是接口类型,但它们都不是另一个的子类型.

From this, glb(C2<?>, C1<T#1>) resolves to the intersection type C2<String> & C1<T#1>, which is invalid, because C2<String> and C1<T#1> are both class types, not interface types, but neither one of them is a subtype of the other.

这种(明显的)规则违规可能在 交集类型的定义本身.

This (apparent) rule violation is perhaps made more clear in the definition of the intersection type itself.

我确定这不是错误,我只是在某处犯了一些简单的错误... 如果是错误,我希望它可以被视为 JLS 中的错误而不是JDK,这样我就可以安全地模拟行为......

I'm sure it's not a bug and I'm just making some simple mistakes somewhere... If it is a bug, I hope it can be considered a bug in the JLS and not the JDK, such that I can expect to be able to safely emulate the behaviour...

感谢您的帮助!

昨天与 Radiodef 交谈后,我说服自己这个问题(或者至少是一种看待它的方式)是 C2 可以有效地将视为C1的子类型,因为T#1只能永远C2满足; 等可以认为等同于它,但是包含和子类型规则没有理解这种关系,因此 JLS 不会识别子类型,应该失败...

After talking with Radiodef yesterday I convinced myself that the issue (or one way of looking at it at least) is that C2<String> can effectively be thought of as a subtype of C1<T#1>, since T#1 can only ever be satisfied by C2<String> and so can be considered equal to it, but the containment and subtyping rules have no understanding of this relationship as written, and so the JLS will not recognise the subtype and should fail...

如果你采用稍微复杂一点的 C1,不过,它更棘手.问题类似,但形成捕获上限的交集类型为 C2&C1<T#2>,似乎无法通过与上述相同的推理得出解决方案.

If you take the slightly more complex case of C1<? extends C2<?>> d;, though, it is more tricky. The problem is similar, but the intersection type which forms the upper bound on the capture comes out as C2<?> & C1<T#2>, where it doesn't seem a solution can be arrived at by the same reasoning as above.

推荐答案

Maurizio 对编译器开发的回应.

(TL;DR javac 确实与此处的规范不一致,最佳解决方案可能介于两种方法之间)

(TL;DR javac is indeed out of alignment with the spec here, and the optimal solution probably lies somewhere between the two approaches)

一个相关的错误可以在这里找到.

非常感谢所有为这个答案做出贡献的人.

Many thanks to all who contributed to this answer.

这篇关于捕获 Java 中的转换问题、JLS 的 WRT 协调和实际 JDK 行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆