The supertype of anonymous class is expected to be a raw type

Georgiy Rakov georgiy.rakov at oracle.com
Mon Aug 3 12:46:05 UTC 2015


Hello,

let's consider following example:

    import java.lang.reflect.Type;import
    java.lang.reflect.ParameterizedType;class MyType<T> {}public class
    Test22 {public static void main(String argv[]) {Bar foo = new
    <String>Bar<String>("str", new MyType()){ };Type actualSuperType =
    foo.getClass().getGenericSuperclass();if ( actualSuperType
    instanceof ParameterizedType )
    {System.out.println("Parameterized");}}}class Bar<T> {public Bar(T
    a1, 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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20150803/f52cf735/attachment.html>


More information about the compiler-dev mailing list