【发布时间】:2014-05-01 04:05:56
【问题描述】:
在 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
【问题讨论】:
-
不清楚您不理解文章的哪一部分(具体而言),因为它很好地解释了这一点。他介绍的类是抽象的,因为由于类型擦除(在文章中对此进行了解释)......这就是它的工作方式。这就是这篇文章的全部内容。您的第二个示例基本上就是重点 - 由于类型擦除,它无法在 Java 中工作。
-
嗨,Brian,我认为这与类型擦除无关,如果我错了,请纠正我。类型擦除意味着在编译期间从源代码中删除泛型类型,JVM 不会在运行时使用它们进行类型检查。但另一方面,这些信息都没有“真正丢失”:它们在编译期间仍然保存在 .class 文件中,因此由类加载器加载到类对象池中。 Java 反射提供了接口让我们检索这些信息。
-
因此,在这两个示例中,类型都被删除了。实际区别在于第一个示例中的“ReferenceType
- >”之类的内容被保存在匿名类的 .class 文件中,而在第二个示例中,“ReferenceType
”被保存。 -
基本上,你的层次太深了。您只能从直接超类中获取泛型类型,并且仅当子类在声明中提供具体类型时。类型擦除会导致你喝酒(相信我)。
标签: java generics types anonymous parameterized-types