[英]Java Generic Class - Determine Type
如果我正在创建一个 java class 是通用的,例如:
public class Foo<T>
如何在内部确定 class,“T”最终是什么?
public ???? Bar()
{
//if its type 1
// do this
//if its type 2
// do this
//if its type 3
// do this
//if its type 4
// do this
}
我查了一下 Java API 并玩过 Reflection 东西,instanceof,getClass,.class 等,但我似乎无法弄清它们的正反面。 我觉得我已经很接近了,只需要合并一些电话,但一直没有接电话。
更具体地说,我试图确定 class 是否使用 3 种可能类型之一进行实例化。
我在几个项目中使用了与他在此处解释的内容类似的解决方案,并发现它非常有用。
http://blog.xebia.com/2009/02/07/acessing-generic-types-at-runtime-in-java/
它的重点是使用以下内容:
public Class returnedClass() {
ParameterizedType parameterizedType = (ParameterizedType)getClass()
.getGenericSuperclass();
return (Class) parameterizedType.getActualTypeArguments()[0];
}
与 .NET Java generics 相比,它们是通过一种称为“类型擦除”的技术实现的。
这意味着编译器在生成 class 文件时将使用类型信息,但不会将此信息传递给字节码。 如果您使用 javap 或类似工具查看已编译的类,您会发现List<String>
是 class 文件中的一个简单List
(属于Object
),就像它在 Java-5 之前的代码中一样。
访问通用 List 的代码将被编译器“重写”,以包含您在早期版本中必须自己编写的强制转换。 实际上,一旦编译器完成了以下两个代码片段,从字节码的角度来看它们是相同的:
Java 5:
List<String> stringList = new ArrayList<String>();
stringList.add("Hello World");
String hw = stringList.get(0);
Java 1.4 及之前版本:
List stringList = new ArrayList();
stringList.add("Hello World");
String hw = (String)stringList.get(0);
当从 Java 5 中的泛型 class 读取值时,会自动插入对已声明类型参数的必要强制转换。 插入时,编译器将检查您尝试输入的值,如果它不是字符串,则会报错并中止。
整个过程是为了保持旧库和新的通用代码的互操作性,而不需要重新编译现有的库。 与 .NET 方式相比,这是一个主要优势,其中通用类和非通用类并存但不能自由互换。
两种方法各有利弊,但 Java 就是这样。
回到原来的问题:您将无法在运行时获取类型信息,因为一旦编译器完成其工作,它就不再存在了。 这在某些方面肯定是有限制的,并且有一些古怪的方法通常基于在某处存储类实例,但这不是标准功能。
如果您知道一些有意义的特定类型,则应该使用实现创建通用类型的子类。
所以
public class Foo<T>
public ???? Bar()
{
//else condition goes here
}
接着
public class DateFoo extends Foo<Date>
public ???? Bar()
{
//Whatever you would have put in if(T == Date) would go here.
}
通用 class 的全部要点是您不需要知道正在使用的类型....
看起来您想要的实际上不是通用 class,而是具有许多不同实现的接口。 但如果你陈述你实际的、具体的目标,也许它会变得更清楚。
我同意面貌。 Generics 用于编译时验证,而不是运行时动态类型。 听起来您真正需要的只是工厂模式。 但是,如果您的“执行此操作”不是实例化,那么一个简单的 Enum 可能也能正常工作。 就像 Michael 所说的,如果您有一个更具体的例子,您会得到更好的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.