Capture conversion issue in Java, WRT reconciliation of JLS and actual JDK behaviour

懵懂的女人 提交于 2019-12-18 14:41:35

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/30788366/capture-conversion-issue-in-java-wrt-reconciliation-of-jls-and-actual-jdk-behav

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!