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

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

问题描述

给定以下两个类定义:

 类C1< T extends C1& {} 

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

考虑以下类型声明:

  C1 <?扩展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 解析为交集类型 C2< String> &因为 C2 C1 / code>都是类类型,而不是接口类型,但是它们都不是其他类型的子类型。



交叉路口类型的定义中更加明确



我确定这不是一个错误,我只是在某处做一些简单的错误... 如果它是一个错误,我希望它可以被认为是JLS中的一个错误,而不是JDK,这样我可以期望能够安全地模拟行为...



感谢任何帮助!



编辑:在与Radiodef昨天谈话后,我说服自己,问题(或一种方式,至少看它) C2< String> 可以有效地被认为是 C1 的子类型$ c>,因为T#1只能由 C2 满足,因此可以认为它等于,但是包含和子类型规则没有理解这种关系的书面,所以JLS不会识别子类型,应该失败...



如果你采取略微更复杂的情况的 C1 <?延伸C 2' d; ,但是,它更棘手。问题是类似的,但是形成捕获的上限的交集类型出现为 C2 <?> &

解决方案。

C1
方案

这个问题最好由 Maurizio对编译器开发的回应



(TL; DR javac确实与规范不符,而最佳解决方案可能位于两种方法)



相关的错误



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


Given the following two class definitions:

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

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

Consider the following type declaration:

C1<? extends C2<String>> c;

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.

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>.

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.

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...

Thanks for any help!

Edit: 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...

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.

解决方案

This question is answered best by Maurizio's response on compiler-dev.

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

An associated bug can be found here.

Many thanks to all who contributed to this answer.

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

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