为什么在java中的“超级类型令牌”模式中需要匿名类

在Neal Gafter的“超类型令牌”模式(http://gafter.blogspot.com/2006/12/super-type-tokens.html)中,一个匿名对象用于传递参数化类型:

class ReferenceType<T>{}

/* anonymous subclass of "ReferenceType" */
ReferenceType<List<Integer>> referenceType = new ReferenceType<List<Integer>>(){

};
Type superClass = b.getClass().getGenericSuperclass();
System.out.println("super type : " + superClass);
Type genericType = ((ParameterizedType)superClass).getActualTypeArguments()[0];
System.out.println("actual parameterized type : " + genericType);

然后结果是:

super type : com.superluli.test.ReferenceType<java.util.List<java.lang.Integer>>
actual parameterized type : java.util.List<java.lang.Integer>

我的问题是,匿名对象“referenceType”做了什么魔术来使它工作?如果我定义了“ReferenceType”的显式子类,并使用它而不是匿名样式,它就不会像预期的那样。

class ReferenceType<T>{}
class ReferenceTypeSub<T> extends ReferenceType<T>{}

/* explicitly(or, named) defined subclass of "ReferenceType" */
ReferenceType<List<Integer>> b = new ReferenceTypeSub<List<Integer>>();
Type superClass = b.getClass().getGenericSuperclass();
System.out.println("super type : " + superClass);
Type genericType = ((ParameterizedType)superClass).getActualTypeArguments()[0];
System.out.println("actual parameterized type : " + genericType);

结果是:

super type : com.superluli.test.ReferenceType<T>
actual parameterized type : T

答案 1

ReferenceType<List<Integer>> referenceType = new ReferenceType<List<Integer>>(){

等效于

public class AnonymousReferenceType extends ReferenceType<List<Integer>> {}
...
ReferenceType<List<Integer>> referenceType = new AnonymousReferenceType();

该黑客围绕Class#getGenericSuperclass()工作,该类指出

返回 Type,该类型表示由此类表示的实体(类、接口、基元类型或 void)的直接超类。如果超类是参数化类型,则返回的对象必须准确地反映源代码中使用的实际类型参数。如果以前未创建过表示超类的参数化类型,则会创建该类型。有关参数化类型的创建过程的语义,请参阅 的声明 。如果这表示 Object 类、接口、基元类型或 ,则返回 。如果此对象表示数组类,则返回表示该类的对象。TypeParameterizedTypeClassvoidnullClassObject

换句话说,的超类是表示 。这有一个实际的类型参数,这是源代码中出现的内容。AnonymousReferenceTypeParameterizedTypeReferenceType<List<Integer>>ParameterizedTypeList<Integer>


在你的第二个例子中,这与你的第一个例子不同

class ReferenceType<T>{}
class ReferenceTypeSub<T> extends ReferenceType<T>{}

的超类(超类型)是一个,其中实际的类型参数是一个 named ,这是源代码中出现的内容。ReferenceTypeSubReferenceType<T>ParameterizedTypeTypeVariableT


要回答您的问题,您不需要匿名课程。您只需要一个子类来声明要使用的类型参数。


答案 2