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

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Mar 11 10:25:06 PDT 2013


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 
> <mailto: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
>     <mailto: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
>>         <mailto: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/2a257ba9/attachment.html 


More information about the compiler-dev mailing list