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

时间:2014-05-01 04:05:57

标签: java generics types anonymous parameterized-types

在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 个答案:

答案 0 :(得分:12)

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)由此类表示。   如果超类是参数化类型,则返回Type对象   必须准确反映源中使用的实际类型参数   代码即可。如果是,则创建表示超类的参数化类型   它之前没有创建过。见宣言   ParameterizedType用于创建过程的语义   参数化类型。如果此Class表示Object类,   接口,基本类型或void,然后返回null。如果   此对象表示数组类,然后表示Class对象   代表Object类的代码将被返回。

换句话说,AnonymousReferenceType的超类是代表ParameterizedType的{​​{1}}。这个ReferenceType<List<Integer>>有一个实际的类型参数,它是ParameterizedType,它出现在源代码中。


在您的第二个示例中,与您的第一个不同,

List<Integer>

class ReferenceType<T>{} class ReferenceTypeSub<T> extends ReferenceType<T>{} 的超类(超级类型)是ReferenceTypeSub,它是ReferenceType<T>,其中实际类型参数是名为ParameterizedType的{​​{1}},这是源代码中出现的内容。


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