Unchecked conversion and super raw type
Alex Buckley
alex.buckley at oracle.com
Fri Aug 23 15:18:40 PDT 2013
I am happy to report that JLS7 makes foo(A<String>) applicable by method
invocation conversion (15.12.2.3), so javac is right to report an ambiguity.
Method invocation conversion allows B to undergo a widening reference
conversion to A, because B's direct supertype is A; and then, because A
is a raw type, an unchecked conversion may be applied from A to A<String>.
Alex
On 4/12/2013 3:25 AM, Maurizio Cimadamore wrote:
> The spec is saying:
>
> "The method m is applicable by subtyping if and only if both of the
> following conditions hold:
>
> For 1 ≤ i ≤ n, either:
>
> Ai <: Si (§4.10), or
>
> Ai is convertible to some type Ci by unchecked conversion (§5.1.9), and
> Ci <: Si."
>
>
> And I agree this seems to be a spec problem - there's no unchecked
> conversion for going from B to A<String>, as unchecked conversion
> requires that source bases type and target nbae type are the same - in
> this case we have that B != A so no unchecked conversion applies.
>
> However, javac (and Eclipse) implement a relaxed check; for example,
> javac is happy whenever it can find a supertype of the LHS type that
> matches the base type of the RHS. Which in this case is satisfied.
>
> Maurizio
>
>
> On 11/04/13 23:40, Zhong Yu wrote:
>>
>>
>>
>> On Thu, Apr 11, 2013 at 5:10 PM, Zhong Yu <zhong.j.yu at gmail.com
>> <mailto:zhong.j.yu at gmail.com>> wrote:
>>
>> Consider this example:
>>
>> public class Test
>> {
>> static class A<T> {}
>>
>> static class B extends A {}
>>
>> void foo(A<String> a) {}
>>
>> void foo(B b) {}
>>
>> void test()
>> {
>> B b = new B();
>> foo(b); // error: reference to foo is ambiguous
>> }
>> }
>>
>> For the method invocation expression `foo(b)`, method `foo(B)` is
>> applicable by subtyping. However is that also true for
>> `foo(A<String>)`? By the letter of the spec, we cannot find a Ci
>> such that "B" is convertible to Ci by unchecked conversion and Ci
>> <: A<String>. So my understanding is that `foo(A<String>)` is not
>> applicable to `foo(b)` by subtyping, and the code should compile
>> since only one applicable method is found during "15.12.2.2. Phase 1"
>>
>>
>>
>> Or, is this a bug of the spec? Maybe the spec intends to say
>>
>> For 1 ≤ /i/ ≤ /n/, either:
>>
>> *
>>
>> A_i |<:| S_i (§4.10
>> <http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.10>),
>> or
>>
>> *
>>
>> A_i |<:| |S_i |
>>
>> The second clause is for the legacy code that saw a non-generic method
>> parameter type.
>>
>> Zhong Yu
>>
>
More information about the compiler-dev
mailing list