Nested generics don't compile in 1.7.0_15, but do in 1.6.0_27.

Dzmitry Lazerka dlazerka at gmail.com
Mon Mar 11 11:21:06 PDT 2013


Thank you! I'll fix the bugs.

-----
Best regards,
Dzmitry Lazerka


On Mon, Mar 11, 2013 at 10:25 AM, Maurizio Cimadamore <
maurizio.cimadamore at oracle.com> wrote:

>  On 11/03/13 17:19, Dzmitry Lazerka wrote:
>
> I've found a workaround: to define
> abstract Class<? /*extends M*/> getModelClass();
> and implement it.
>
> Yep - was just thinking about the same
>
>  Although then we're not using compile-type checks, that were possible in
> openjdk 1.6.0.
>
> Well, yes - but the fact that those checks were working was a bug. ;-)
> As in my first email, it's possible that there's something that could be
> loosened at the spec level - but for consistency sake it make sense for now
> to treat your example as if it were
>
> class HasId<I> {}
>  class Alert<T extends /*Some*/Object> extends _HasId<String>_ {}
> class BaseController<M extends HasId<String>> {
>     // abstract Class<M> getModelClass();
> }
>
>
> Maurizio
>
>
> -----
> Best regards,
> Dzmitry Lazerka
>
>
> On Mon, Mar 11, 2013 at 10:08 AM, Dzmitry Lazerka <dlazerka at gmail.com>wrote:
>
>> Of course, but then how to return Class<Alert<?>>?
>>  AlertController.java:13: error: incompatible types
>>         return Alert.class;
>>                     ^
>>   required: Class<Alert<?>>
>>   found:    Class<Alert>
>> 1 error
>>
>>  And it's not possible to cast Class<Alert> to Class<Alert<?>>, types
>> are incompatible.
>>
>> -----
>> Best regards,
>> Dzmitry Lazerka
>>
>>
>>   On Mon, Mar 11, 2013 at 10:05 AM, Maurizio Cimadamore <
>> maurizio.cimadamore at oracle.com> wrote:
>>
>>>  On 11/03/13 17:02, Dzmitry Lazerka wrote:
>>>
>>> By the way, override wouldn't work, and I don't see any workaround:
>>>
>>>  AlertController.java:11: error: AlertController is not abstract and
>>> does not override abstract method getModelClass() in BaseController
>>> class AlertController extends BaseController<Alert<?>> {
>>> ^
>>> AlertController.java:12: error: getModelClass() in AlertController
>>> cannot override getModelClass() in BaseController
>>>     Class<Alert> getModelClass() {
>>>                  ^
>>>   return type Class<Alert> is not compatible with Class<Alert<?>>
>>>   where M is a type-variable:
>>>     M extends HasId<String> declared in class BaseController
>>> 2 errors
>>>
>>>   The return type in AlertController should match the one in the
>>> superclass - if you had Class<M> in the super class and M is Alert<?> in
>>> the subclass, the return type should be Class<Alert<?>>.
>>>
>>> Maurizio
>>>
>>>
>>> -----
>>> Best regards,
>>> Dzmitry Lazerka
>>>
>>>
>>> On Mon, Mar 11, 2013 at 3:41 AM, Maurizio Cimadamore <
>>> maurizio.cimadamore at oracle.com> wrote:
>>>
>>>>  Hi,
>>>> (cc'ing Alex)
>>>> if you do:
>>>>
>>>> class AlertController extends BaseController<Alert<Object>>
>>>>
>>>> or
>>>>
>>>> class AlertController extends BaseController<Alert<?>>
>>>>
>>>> The code and the override should compile.
>>>>
>>>> Said that, the behavior in JDK 7 is deliberate - the supertypes of a
>>>> raw type are all erased, which means the supertype of Alert is just HasId
>>>> and not HasId<String> as you would expect. This is the result of this fix:
>>>>
>>>> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6559182
>>>>
>>>> Alex, can you comment on this? JLS section on raw types (4.8) only says
>>>> that the supertypes of a raw type are the erasure of such sypertypes - it
>>>> doesn't say this should be applied transitively. Also, Definition of type
>>>> erasure (4.6) doesn't say anything about supertypes.
>>>>
>>>> The rationale behind the fix for 6559182 is that all supertypes of a
>>>> raw type should be erased - which seems a fair assumption when looking at
>>>> the examples in 6559182 - however, should those two cases be treated
>>>> differently:
>>>>
>>>> Case A:
>>>>
>>>> class Foo<X> { }
>>>> class SubFoo<X> extends Foo<String> { }
>>>>
>>>> SubFoo sf = ...;
>>>>
>>>> Case B:
>>>>
>>>> class Foo<X> { }
>>>> class FooString extends Foo<String> { }
>>>> class SubFoo<X> extends FooString { }
>>>>
>>>> SubFoo sf = ...;
>>>>
>>>> In other words, is the fact that example (B) is using an intermediate
>>>> supertype that is not parameterized (but has parameterized supertype)
>>>> enough top warrant special treatment?
>>>>
>>>>
>>>> Maurizio
>>>>
>>>>
>>>> On 11/03/13 03:25, Dzmitry Lazerka wrote:
>>>>
>>>> Hi,
>>>>
>>>>  class HasId<I> {}
>>>> class HasStringId extends HasId<String> {}
>>>> class Alert<T extends /*Some*/Object> extends HasStringId {}
>>>> class BaseController<M extends HasId<String>> {
>>>>     // abstract Class<M> getModelClass();
>>>> }
>>>> class AlertController extends BaseController<Alert> { // error here
>>>>     // @Override Class<Alert> getModelClass() {
>>>>     //     return Alert.class;
>>>>     // }
>>>> }
>>>> compiles fine on OpenJDK6, but in OpenJDK7 gives:
>>>>
>>>>  Controller.java:50: error: type argument Alert is not within bounds of
>>>>     type-variable T
>>>> class Controller extends BaseController<Alert> {
>>>>                                         ^
>>>>   where T is a type-variable:
>>>>     T extends HasId<String> declared in class BaseController
>>>>
>>>>  Note that there's rawtype warning at line 50, because Alert must be
>>>> parameterized. If I do that, e.g. extends BaseController<Alert<Object>>,
>>>> code compiles. But I cannot do that, because I need to implement
>>>> getModelClass().
>>>>
>>>>  Ubuntu 12.04.
>>>>
>>>>  Is it a bug in 1.7.0_15? Can you suggest any workarounds?
>>>>
>>>> -----
>>>> Best regards,
>>>> Dzmitry Lazerka
>>>>
>>>>
>>>>
>>>
>>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20130311/4e350dc2/attachment.html 


More information about the compiler-dev mailing list