public void example(Object o) {
if(o instanceof List<MyType>)
//do something
}
我明白,这是不可能的(和为什么它是不可能的)给定的Java泛型处理和类型擦除方式。
我的问题是,什么是最好/最干净的方式来实现这一目标?或者我唯一能做的就是检查o
是否为List<?>
?
public void example(Object o) {
if(o instanceof List<MyType>)
//do something
}
我明白,这是不可能的(和为什么它是不可能的)给定的Java泛型处理和类型擦除方式。
我的问题是,什么是最好/最干净的方式来实现这一目标?或者我唯一能做的就是检查o
是否为List<?>
?
也许通过检查在运行时的对象类型,也许是这样的:
if (o.getClass() == List.class) ...
很明显,你必须深入挖掘对象的类类型,看它是否是一个精确匹配List<>
和列表的元素类型。
在运行时,列表
看起来'List'是一个接口,这可能是一个坏主意 – 2010-02-10 03:13:51
短检查类型列表中所有的项目,它是无法确定Java中的泛型参数的类型,因为这只是存在在编译时和运行时之前被移除。
我的建议是,除非你绝对需要让方法接受一个对象(例如符合接口规范或覆盖Object.equals),以便将所需的正确类型作为该方法的参数,并且用可能需要运行该方法的各种其他类型重载该方法。
您不能检查超过o instanceof List<?>
。
您从Java泛型中获得的类型安全性仅在编译时发生。 像你这样的方法(它接受一个对象,然后试图弄清楚该怎么做),在这个设计中效果并不好。 我明白为什么这样一个动态的方法是必要的一段时间,但考虑版本补充它输入参数:
public void example(Object o) {
if(o instanceof List<?>)
example((List)o); // can only hope that the type is correct here
}
public void example(List<MyType> list){
// do something
}
在那些可以使用的情况下,你获得仿制药的全部好处。在其他情况下,你必须依靠阅读你的Javadoc的人,并只传递正确的类型。
什么甚至以上方法不能做的是有List<TypeA>
和List<TypeB>
两个不同的代码路径。如果这对你来说真的需要,可以考虑使用自己的包装类型ListOfTypeA
,ListOfTypeB
。
取决于你需要做什么,甚至有可能不会有必要看看删除类型列表中作为一个整体,只是在运行时类型的各个元件的工作:
for (Object o: list){
if (o instanceof TypeA){
}
if (o instanceof TypeB){
}
}
Java在编译后会擦除泛型的类型信息,所以您不能以这种方式动态地检查类型参数。
如果这个代码的所有路径限制类型参数,然后做:
// Return true if object is a list of MyType, false if it is not a list, or is
// empty
boolean isListOfMyType(Object o) {
if (o instanceof List) {
List<?> l = (List<?) o;
return (l.size() > 0 && (l.get(0) instanceof MyType)
}
return true;
}
是类型安全的,但如果该列表不为空时才会有效。如果不是,您需要修改上述内容以检查所有项目是否通过了instanceof测试(或者如果您允许列表中有空值,则它们为空)。
另一种替代方法是创建一个子类,该子类扩展为ArrayList<MyType>
并使用 这表示您的instanceof
检查。
最后但并非最不重要的一个实现List<MyType>
的子类将允许您使用Class.getGenericInterfaces()
方法获取类型参数。有关详细信息,请参见this。
对于上述两种方法中的任何一种,您必须确保创建列表总是实例化这些类型之一。 IE浏览器。如果调用者去构建他们自己的ArrayList<MyType>
,它将无法工作。
与普遍接受的相反,很少知道类型擦除可以避免,这意味着被叫方确实有能力知道在通话过程中使用了哪些通用参数。
请看看: Using TypeTokens to retrieve generic parameters
感谢
这个问题听起来很熟悉,好像人被要求在过去90天左右。尝试查看[http://stackoverflow.com/questions/1004022/java-generic-class-determine-type]。 – 2010-02-10 03:19:50