2012-09-06 49 views
1

的Java是不是让我加类型声明的子类,这个类Java泛型插入的通配符

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>()); 
    } 
} 

如果鉴定是问题的一个子类。

,这我holder类看起来像

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>) 
+0

有什么编译器错误? – vulkanino

+0

@vulkanino更新了它。 – user962206

+1

'Identification'是'Question'的子类,而你在'set'中声明它应该是一个超类。 – vulkanino

回答

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>

+0

我期待看到它会接受任何事情,只要它延伸T或在这个任何延伸问题 – user962206

+0

为什么不允许有持有人不是问题的子类? – user962206

+0

你能提供一个例子吗? – user962206

1

Exam<T>预计Holder<T>可以容纳T的任何子类。这就是super所做的。您正在传递Holder<Identification>,但Identification既不是T也不是它的超类。

+0

那它有什么区别?扩展T? – user962206

+0

@ user962206'持有者'意味着该方法期望**任何可以持有T子类的持有者**。然后您可以传递持有者<标识符>,但不能使用Holder.set(T) '因为'T'在这方面是未知的。然而,'Holder.get()'是可行的,因为'T'返回**必须**是'Exam'的'T'的子类。 –

0

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

0

它的工作原理(但具有不同的含义,当然),如果你写的类枚举的

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

变更集方法

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

}