我怎样才能在java中编写这段代码?
public class ComponentsManager
{
private List<IComponent> list = new ArrayList<IComponent>();
public <U extends IComponent> U GetComponent() {
for (IComponent component : list) {
if(component instanceof U)
{
return component;
}
}
}
}
但我无法对泛型类型执行instanceof。我该怎么办? 感谢。
答案 0 :(得分:22)
由于类型擦除,基本上你不能这样做。正常的解决方法是将Class
对象作为参数传递; e.g。
public <U extends IComponent> U GetComponent(Class<U> clazz) {
for (IComponent component : list) {
if (clazz.isInstance(component)) {
return clazz.cast(component);
}
}
}
你也可以使用if (clazz.equals(component.getClass())) { ...
,但这确实是类型匹配...这不是instanceof
运算符所做的。 instanceof
运算符和Class.instanceOf
方法都会测试值的类型是否与赋值兼容。
答案 1 :(得分:2)
据我所知,你不能。您必须将Class
对象作为参数:
public <U extends IComponent> U getComponent(Class<U> clazz) {
// ...
if (component.getClass() == clazz) {
return (U) component;
}
}
并称之为:
getComponent(MyComponentImpl.class);
答案 2 :(得分:2)
使用java的常规规则 - 如果泛型类需要知道其泛型类型,则必须传递提示。解决该问题的常用方法是使用构造函数:
public class ComponentsManager<U extends IComponent> {
private Class<U extends IComponentManeger> genericType = null;
public ComponentsManager<U extends IComponent>(
Class<U extends IComponent> genericType) {
this.genericType = genericType;
}
}
现在,类知道它是泛型类,如果集合中的组件与类泛型类型匹配,则可以使用泛型类实例来验证。
答案 3 :(得分:2)
您可以尝试添加一些“测试”方法:
private static <U extends IComponent> boolean testComponent(U u) {
return true;
}
private static boolean testComponent(Object o) {
return false;
}
然后,使用testComponent(component)
代替component instanceof U
。
示例代码:
import java.util.*;
class IComponent {
}
class T1 extends IComponent {
}
public class Test {
public static <U extends IComponent> boolean testComponent(U u) {
return true;
}
public static boolean testComponent(Object o) {
return false;
}
public static void main(String[] args) {
T1 t = new T1();
System.out.println("hm? " + (testComponent(t) ? "true" : "false"));
}
}
<强>输出:强>
HM?真
答案 4 :(得分:0)
完全通用的类型不能被视为代码中的正常变量,这使得很难直接进行比较。但是,反射类ParameterizedType
可以帮助您获得表示参数化类型的实例,这基本上是可行的对象。
Type genericSuperType = object.getClass().getGenericSuperclass()
Type[] actualTypeParams = ((ParameterizedType) genericSuperType).getActualTypeArguments()
if (actualTypeParams[0] instanceof Class) {
((Class) actualTypeParams[0]).isInstance(testingObj);
}
有关ParameterizedType
和相应TypeVariable
上的用法的更多详细信息,可以引用内部工具类TypeParameterMatcher`, in Netty。