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 10:19:48 PDT 2013


I've found a workaround: to define
abstract Class<? /*extends M*/> getModelClass();
and implement it.
Although then we're not using compile-type checks, that were possible in
openjdk 1.6.0.

-----
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/93a855ad/attachment.html 


More information about the compiler-dev mailing list