如何在<base type =“”/>列表中查找并返回<derived type =“”>的对象?

时间:2015-10-01 16:57:16

标签: java generics reflection

情景:

  • 我有一个类型为Component的私有列表(其中Component是一个 抽象类)
  • 此列表具有任意数量的不同Component子类 (其中每个派生类型在该列表中是唯一的)
  • 我想提供一种允许用户查找的方法 特定组件的偏好

我的尝试:

private ArrayList<Component> components = new ArrayList<Component>();

public <T extends Component> T getComponent( T type )
{
    for ( Component c : components )
    {
        if ( c instanceof T )
        {
            return (T) c;
        }
    }
    return null;
}

编译器在if语句上报告以下错误:

  

无法对类型参数T执行instanceof检查。请使用其擦除组件,因为在运行时将删除其他泛型类型信息

实现此行为的推荐方法是什么?

2 个答案:

答案 0 :(得分:2)

您可能希望依赖Class.isInstanceOf(Object)

for (Component c : components) {
     if (type.getClass().isInstance(c)) {
         return (T) c;
     }
}
  

确定指定的Object是否与此Class表示的对象分配兼容。此方法是Java语言instanceof运算符的动态等效项。

提供Class实例而不是对象更有意义:

public <T extends Component> T getComponent(Class<T> type)
{
    for (Component c : components) {
         if (type.isInstance(c)) {
             return (T) c;
         }
    }
    return null;
}

答案 1 :(得分:1)

编译器很清楚

  

使用其擦除组件

您可以将参数T type替换为Component c

之后你只需要提取c的类型(它将是一个实现,因此c.getClass()将是一个扩展Component的类。)

您应该检查类型是否匹配并返回第一个元素。

private ArrayList<Component> components = new ArrayList<Component>();

public <T extends Component> T getComponent( Component component )
{
    for ( Component c : components )
    {
        if ( c.getClass().equals(component.getClass()) )
        {
            return c;
        }
    }
    return null;
}

我认为它应该运作良好。

我希望它有所帮助