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