The supertype of anonymous class is expected to be a raw type
Alex Buckley
alex.buckley at oracle.com
Mon Aug 3 18:53:42 UTC 2015
Georgiy,
Good analysis but you have a non-generic ctor in class Bar<T> (the class
is generic but the ctor isn't). You also seem to say that the return
type of the method derived from the ctor is MyType, but it's obviously Bar.
I don't actually disagree with your conclusion since 15.12.2.6 would
still give raw Bar as the return type for the non-generic ctor. But it
would be helpful to clarify your mail and restart the thread.
Alex
On 8/3/2015 5:46 AM, Georgiy Rakov wrote:
> Hello,
>
> let's consider following example:
>
> importjava.lang.reflect.Type;
> importjava.lang.reflect.ParameterizedType;
>
> classMyType<T> {}
>
> public classTest22 {
> public static voidmain(String argv[]) {
> Bar foo =new<String>Bar<String>("str",newMyType()){ };
> Type actualSuperType = foo.getClass().getGenericSuperclass();
> if( actualSuperTypeinstanceofParameterizedType ) {
> System.out.println("Parameterized");
> }
> }
> }
>
> classBar<T> {
> publicBar(Ta1, MyType<String> a2){ }
> }
>
> When compiled and run by JDK9b75 "Parameterized" is printed. However
> according to my understanding it shouldn't have to. The reasons for this
> are presented below: 1. According to the following assertion specified
> in JDK-8073593
> <https://bugs.openjdk.java.net/browse/JDK-8073593?focusedCommentId=13612188&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13612188>
> the superclass of anonymous class should be equal to the return type of
> the method derived from Bar class constructor:
>
> - The superclass or superinterface type of the anonymous class is
> the return type, T, determined for mj (15.12.2.6).
>
> 2. The second actual argument for the constructor is of a raw type
> MyType while the corresponding formal parameter is a parameterized type
> MyType<String>. So unchecked conversion is necessary in order for the
> only Bar constructor to become applicable for the provided invocation.
> 3. According to assertion presented above the return type is determined
> by 15.12.2.6 which states following:
>
> * If the chosen method is generic and the method invocation provides
> explicit type arguments, let Pi be the type parameters of the method
> and let Ti be the explicit type arguments provided for the method
> invocation (1 ≤ i ≤ p). Then:
> o If unchecked conversion was necessary for the method to be
> applicable, then the invocation type's parameter types are
> obtained by applying the substitution [P1:=T1, ..., Pp:=Tp] to
> the parameter types of the method's type, and the invocation
> type's return type and thrown types are given by the erasure of
> the return type and thrown types of the method's type.
>
> Namely it says that the return type of the invocation type is the
> erasure of the return type of the method's type, provided unchecked
> conversion was necessary for the method to be applicable. According to
> step 2 unchecked conversion was necessary for the method to be
> applicable so the return type of the method is the erasure of MyType<!
> T>, i .e. MyType. 4. So according to step 1 given above the superclass
> of the anonymous class is MyType which is a raw type, that is, it
> shouldn't not considered as a parameterized one. 5. As a
> resultgetGenericSuperclass method should return an instance of a class
> not implementing ParameterizedType interface, but actually it returns an
> instance of a class implementing ParameterizedType interface. Could you
> please tell if you consider this as a bug. Please note that javap prints
> following when it runs against anonymous class Test22$1:
>
> final class Test22$1 extends *Bar<java.lang.String>* {
> Test22$1(java.lang.String, MyType);}
>
> So if this is a bug it seems to be javac bug. Thanks, Georgiy.
More information about the compiler-dev
mailing list