2012-09-06 117 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){ 

}