如何比较对象实例的类型与泛型类型?

时间:2011-05-17 11:14:50

标签: java generics reflection

我怎样才能在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。我该怎么办? 感谢。

5 个答案:

答案 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