调用具有泛型类型参数的方法的问题

时间:2012-03-09 14:44:00

标签: java eclipse generics

我对泛型有一些问题,让我解释一下。

我有一个包装LinkedList的类:

public class IdnList<T extends Numerable> extends IdnElement implements List<T> {

    private LinkedList<T> linkedList;

    @Override
    public boolean add(T e){
       return linkedList.add(e);
    }

   //stuff  
}

请注意此类T的通用类型extends Numerable接口。

好的,现在在另一个类中,我想调用此方法,如下所示:

 if(childToAdd instanceof Numerable)
 ((IdnList<?>)this).add((Numerable)childToAdd);

但是eclipse说:The method add(capture#1-of ?) in the type IdnList<capture#1-of ?> is not applicable for the arguments (Numerable),我真的无法弄清楚它为什么不起作用。为什么我不能在列表中添加Numerable对象? 我错过了什么?

修改 这是一部经典之作。你问,然后你找到了一个线索。似乎解决方法是:

  ((IdnList<Numerable>)this).add((Numerable)childToAdd);

但我不知道它有多优雅。我非常感谢您的进一步评论。

2 个答案:

答案 0 :(得分:2)

假设您的课程AB都延伸Numerable。然后有三种有效类型IdnListIdnList<A>IdnList<B>IdnList<Numerable>

我希望您同意您不能将任何Numerable添加到IdnList<A>

现在,在这行代码中,编译器如何知道您是否正确匹配了类型?

(IdnList<?>)this).add((Numerable)childToAdd);

它只知道childToAddNumerable,而this是某种IdnList。它不知道是什么类型,因此无法保证类型安全。请记住,泛型类型检查完全在编译时完成,而不是运行时。

我看到变通方法如何允许代码编译,但我不确定它的风险是什么。在我看来,由于泛型类型参数在运行时被擦除,基本上你只是绕过所有类型检查。

答案 1 :(得分:1)

问题在于引用其他类中的IdnList实例。 我在你的代码示例中看不到它,但看起来它没有与之关联的正确类型,特别是当它被强制转换为通配符时。

由于IdnList需要为每个实例设置一个类型(T),因此编译器无法知道您要执行的操作。

如果您对IdnList的引用具有与之关联的正确类型,它将接受T的任何子类,如下所示:

  IdnList<Numerable> list = new IdnList<Numerable>();
  list.add(new Numerable());
  list.add(new AnotherType());
  list.add(new YetAnotherType());

(鉴于AnotherType和YetAnotherType是Numerable的子类)

由于您对实例的引用没有设置任何类型,我猜你实际上要做的是:

public class IdnList extends IdnElement implements List<Numerable> {

    private LinkedList<Numerable> linkedList;

    @Override
    public boolean add(Numerable e) {
        return linkedList.add(e);
    }
}