Java泛型插入通配符

时间:2012-09-06 10:54:24

标签: java generics wildcard

Java不允许我在此类

中添加Type声明的子类
public class Exam<T> {

    public  void set(Holder<? super T> hold){

    }
    public  T get(Holder<? extends T> holder){ return holder.get();}


    public static void main (String[] args){
        Exam<Question> eq = new Exam<Question>();
        eq.set(new Holder<Identification>());
    }
}

识别是问题的子类。

这就是我的持有人类看起来像

public class Holder<T> {
    T item;

    public void set(T item){ this.item = item; }
    public T get(){return item;}
}

错误

The method set(Holder<? super Question>) in the type Exam<Question> is not applicable for the arguments (Holder<Identification>)

5 个答案:

答案 0 :(得分:5)

该错误对我来说看起来很不言自明 - set方法需要Holder<? super Question>,并且您试图为它提供Question的子类的持有者。如上所述,Exam.set可以采用Holder<Object>,但不能采用Holder<Identification>

在泛型中考虑extendssuper的好方法是分配:T extends Foo将接受您可以在右侧使用的任何类型T在没有强制转换的情况下转让给Foo的一方,即

Foo something = new T();

(将其视为伪代码 - 我知道你真的不允许new类型变量。相反,T super Foo接受任何可以在作业左侧使用的T而不进行投射:

T myThing = new Foo();

在您的具体示例中,如果没有强制转换,Identification i = new Question()不合法,因此Holder<? super Question>参数无法接受Holder<Identification>值。

答案 1 :(得分:1)

Exam<T>期望Holder<T>可以容纳 T 的任何子类。这就是super的作用。您传递的是Holder<Identification>,但Identification既不是T也不是超类。

答案 2 :(得分:1)

将类Enum的set方法更改为

public  void set(Holder<? extends T> hold){

}

答案 3 :(得分:0)

Generic是不变的。这可能是你的答案。 Invariant意味着Type2是Type1的子类,因此它并不意味着List是List。

答案 4 :(得分:0)

如果你写

,它有效(但当然有不同的含义)
public  void set(Holder<? extends T> hold){ }