Type variable as wildcard bound
Rémi Forax
forax at univ-mlv.fr
Thu Nov 17 05:37:09 PST 2011
On 11/17/2011 01:43 PM, Maurizio Cimadamore wrote:
> On 15/11/11 23:23, Zhong Yu wrote:
>> Hi team, I don't understand the behavior of javac7 u2 b11 on the following code:
>>
>> class G<N extends Number> {}
>>
>> <T> void f1(G<? extends T> k){} //error. why?
>>
>> <T> void f2(G<? super T> k){} //ok. why?
>>
>> With capture conversion applied, in f1, we have upper bound T&Number,
>> lower bound null. I don't see any problem here, even if for some T,
>> T&Number=null. Is the combination of T&Number illegal?
>>
>> In f2, we have upper bound Number, lower bound T. Since it's not true
>> that T<:Number, I don't see why this should compile.
> The failure you are seeing is caused by the following statement in JLS
> section 5.1.10:
>
> "If/T_i /is a wildcard type argument of the form|? extends|/B_i /,
> then/S_i /is a fresh type variable whose upper bound is/glb(B_i /,/U_i
> [A_1 /:=/S_1 , ..., A_n /:=/S_n ]/) and whose lower bound is the null
> type, where/glb(V_1 ,... ,V_m )/is/V_1 & ... & V_m /. _It is a
> compile-time error if for any two classes (not interfaces)__/V_i
> /and/V_j ,V_i /is not a subclass of/V_j /__or vice versa._"
>
> Historically, javac has always interpreted the underlined text very
> strictly - meaning that glb(T, Number) where T is a type-variable
> (whose bound is Object) does not exist, as neither T <: Number nor
> Number <: T. As such, the capture conversion for G<? extends T> does
> not exist.
>
> While Javac 1.6 didn't complain about that specific code, it still
> ended up in calculating an erroneous glb - which then led to bad
> programs like the following to compile without errors:
>
> class G<N extends Number> {
> private N n;
> G(N n) { this.n = n; }
> N g() { return n; };
> }
>
> class Test {
> static <T> void f1(G<? extends T> k){ String s = k.g(); }
>
> public static void main(String[] args) {
> Test.f1(new G<Integer>(1)); //throws CCE at runtime!!!
> }
> }
>
> In JDK 7 we made these error manifests, so that the glb computation
> failure is now explicit. This way no unsound programs will be accepted
> (and, as a side-effect, we got rid of a number of javac crashes
> related to the fact that javac needed to hanlde this erroneous
> captured type).
>
> We will consider as to whether the above JLS paragraph needs rewording
> and, perhaps, to be loosened, in order to allow glb(T, Number) to
> yield T & Number.
>
> Thanks
> Maurizio
but T can represent a class, so I don't see how T & Number can be valid ?
Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20111117/85e35ba9/attachment.html
More information about the compiler-dev
mailing list