为什么在“超级类型令牌”中需要匿名类在java中的模式 [英] Why is anonymous class required in "super type token" pattern in java

查看:215
本文介绍了为什么在“超级类型令牌”中需要匿名类在java中的模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Neal Gafter的超级类型令牌模式( http://gafter.blogspot.com /2006/12/super-type-tokens.html ),使用匿名对象传入参数化类型:

  class ReferenceType< T> {} 

/ * ReferenceType的匿名子类* /
ReferenceType< List< Integer>> referenceType = new ReferenceType< List< Integer>>(){

};
类型superClass = b.getClass()。getGenericSuperclass();
System.out.println(super type:+ superClass);
类型genericType =((ParameterizedType)superClass).getActualTypeArguments()[0];
System.out.println(实际参数化类型:+ genericType);

然后结果是:
$ b $

  super类型:com.superluli.test.ReferenceType< java.util.List< java.lang.Integer>> 
实际参数化类型:java.util.List< java.lang.Integer>

我的问题是,匿名对象referenceType做什么神奇的工作?如果我定义了一个ReferenceType的显式子类并使用它来代替匿名样式,那么它并不如预期的那样。

  class ReferenceType< T> {} 
class ReferenceTypeSub< T>扩展ReferenceType< T> {}

/ *显式地(或命名)定义了ReferenceType的子类* /
ReferenceType< List< Integer>> b = new ReferenceTypeSub< List< Integer>>();
类型superClass = b.getClass()。getGenericSuperclass();
System.out.println(super type:+ superClass);
类型genericType =((ParameterizedType)superClass).getActualTypeArguments()[0];
System.out.println(实际参数化类型:+ genericType);

结果是:

pre > super类型:com.superluli.test.ReferenceType< T>
实际参数化类型:T


解决方案

/ p>

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

等价于

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

黑客可以在 Class#getGenericSuperclass() 其中声明

$


返回表示实体
的直接超类的类型接口,原始类型或void)。

如果超类是参数化类型,则 Type 返回的对象
必须准确反映源
代码
中使用的实际类型参数。如果之前尚未创建
,则会创建表示超类的参数化类型。有关
参数化类型的创建过程的语义,请参阅
ParameterizedType 的声明。如果 Class 代表Object类,
接口,原始类型或 void ,则返回 null 。如果
这个对象表示一个数组类,那么表示 Object 类的 Class 对象
是返回。

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






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

  class ReferenceType< T> {} 
class ReferenceTypeSub< T>扩展ReferenceType< T> {}

的超类(超类型) ReferenceTypeSub 是一个 ReferenceType< T> ,它是一个 ParameterizedType 一个 TypeVariable 命名为 T ,这就是源代码中出现的内容。






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


In Neal Gafter's "super type token" pattern (http://gafter.blogspot.com/2006/12/super-type-tokens.html), an anonymous object was used to pass in the parameterized type :

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);

Then result is :

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

My question is, what the magic does the anonymous object "referenceType" do to make it work? If I define a explicit subclass of "ReferenceType" and use it instead of the anonymous style, it doesn't as expected.

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);

The result is :

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

解决方案

This

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

is equivalent to

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

The hack works around Class#getGenericSuperclass() which states

Returns the Type representing the direct superclass of the entity (class, interface, primitive type or void) represented by this Class. If the superclass is a parameterized type, the Type object returned must accurately reflect the actual type parameters used in the source code. The parameterized type representing the superclass is created if it had not been created before. See the declaration of ParameterizedType for the semantics of the creation process for parameterized types. If this Class represents either the Object class, an interface, a primitive type, or void, then null is returned. If this object represents an array class then the Class object representing the Object class is returned.

In other words, the superclass of AnonymousReferenceType is a ParameterizedType representing ReferenceType<List<Integer>>. This ParameterizedType has an actual type argument and that is a List<Integer> which is what appears in the source code.


In your second example, which is not the same as your first,

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

the super class (super type) of ReferenceTypeSub is a ReferenceType<T> which is a ParameterizedType where the actual type argument is a TypeVariable named T, which is what appears in the source code.


To answer your question, you don't need an anonymous class. You just need a sub class which declares the type argument you want to use.

这篇关于为什么在“超级类型令牌”中需要匿名类在java中的模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆