[英]Generics: How to capture a wildcard?
不,這個問題不是關於它們之間的區別嗎? 和T; 這是關於我如何變成<? >參數命名為<T>。 考慮這個示例代碼:
import java.io.Serializable;
class A<T extends Serializable> {
<S extends Serializable> void bar(S arg) { }
void bar2(T arg) { }
}
public class B {
A<? extends Serializable> myA = null;
<T extends Serializable> void foo(T arg) {
myA.bar(arg);
myA.bar2(arg);
}
}
我的問題是上面沒有編譯的事實; 對bar2()的調用給了我
The method bar2(capture#2-of ? extends Serializable) in the type
A<capture#2-of ? extends Serializable> is not applicable for the arguments (T)
我猜這個“原因”是myA是<? extends Serializable> ; 但B.foo中的T ......很好,一個名叫T; 而不是通配符?
“修復”這種方法的一種方法是使<T extends Serializable>為B類的類型參數...但這基本上與我對該類的其他用法沖突。 含義:我最終寫下了B及其成員myA,這完全是因為我不想參數化B類。 所以,我開始只使用bar2()方法; 然后稍后添加了bar()......但這並沒有真正幫助。
那么 - 有沒有辦法讓我的班級B在我的示例代碼中使用A.bar2()作為“預期”?
編輯:而且確切地說 - bar()方法對我沒有幫助; 因為那里的“S”......與我在A班中真正使用的“T”不兼容。
你走到了盡頭。
A<? extends Serializable> myA = ...;
所以myA
是A
的未知的東西。 它可以是A<String>
,或A<Integer>
或A<Banana>
。 你只是不知道。 讓我們說這是一個A<Banana>
。
<T extends Serializable> void foo(T arg) {
所以foo()
接受任何可序列化的:String,Integer,Banana,Apple,等等。 假設它以Integer
作為參數調用。
myA.bar2(arg);
因此,基於上面的假設,雖然myA
是A<Banana>
,但它會調用bar2()
並將Integer作為參數。 編譯器無法接受這一點:它顯然不是類型安全的。 B
必須是通用的。
@JBNizet已經解釋了為什么不能這樣做。 這個答案旨在解釋你可能有的選擇(其中一個在你的問題中正確指出,但這不是唯一的選擇)。
使B采用類型參數
class B<T extends Serializable> {
A<T> myA = null;
void foo(T arg) {
myA.bar(arg);
myA.bar2(arg);
}
}
使B從A延伸(如果B通過A的a-a測試)
class B extends A<String> {
public void foo(String arg) {
bar2(arg);
bar(1);
}
}
兩個選項之間的區別在於:1) bar
和bar2
需要傳遞相同的類型,其中2) bar
和bar2
可以傳遞不同的類型,因為bar2
由為A
聲明的類型參數綁定,其中bar
是由為方法聲明的類型參數綁定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.