(要清理的問題,「T」指的是類聲明的類型參數)爲什麼java.lang.Class的getInterfaces()方法返回類<?> []而不是類<? super T> []?
只是作爲一個例子,請查看以下應用:
public class TestClass {
interface InterfaceA{}
interface InterfaceB{}
interface InterfaceC{}
class ClassA implements InterfaceA, InterfaceB, InterfaceC{}
public static void main(String[] args){
Class<? super ClassA> superClass1 = ClassA.class;
Class<? super ClassA> superclass2 = InterfaceA.class;
Class<? super ClassA> superclass3 = InterfaceB.class;
Class<? super ClassA> superclass4 = InterfaceC.class;
for(Class<?> clazz : ClassA.class.getInterfaces()){
System.out.println(clazz.getName());
}
}
}
的輸出是一個可以預料到的:
TestClass$InterfaceA
TestClass$InterfaceB
TestClass$InterfaceC
因此,基於以上這個例子中,我們可以看到,編譯器識別出了InterfaceA 確實次相遇通配符的邊界,所有其他接口也是如此。
直覺上,我希望下面是安全的,但它不是:
Class<? super ClassA>[] interfaces = ClassA.class.getInterfaces();
,編譯器會發出警告,因爲簽名說,它返回類;但是,對於類的Javadoc指出以下:
如果該對象表示一個類,返回值是一個數組 表示由 類實現的所有接口包含對象。
'本對象'在本例中是指ClassA
。在此基礎上聲明,如果我們致電:
ClassA.class.getInterfaces()
那麼我們就知道,在邏輯上,返回的陣列中的每個Class<?>
將包含一個超類型的ClassA
參考。
作爲參考的另外一點:
在Java語言參考,第三版:
類必然實現所有的直接 超和直接超級做接口。該(多)接口繼承允許對象支持(多個)共同行爲 而不共享任何實現。
讀這篇文章的其他部分規格,我認爲任何類或接口實現或exteneded一類T
會落入邊界<? super T>
。
編輯:
有人提出,我的問題沒有具體的理由。我會提供一個例子:
1 import java.util.Map;
2 import java.util.HashMap;
3
4 public class MapWrapper<T> {
5 private final Map<Class<?>, OtherClass<T,?>> map = new HashMap <Class<?>, OtherClass<T,?>>();
6
7 public <W> void addToMap(Class<W> type, OtherClass<T,? super W> otherClass){
8 map.put(type, otherClass);
9 }
10
11 public <W> OtherClass<T,? super W> getOtherClassForAnyInterface(Class<W> type){
12 if(type.getInterfaces()!=null){
13 for(Class<?> interfaceType : type.getInterfaces()){
14 // Here, a cast is necessary. It throws a compiler warning for unchecked operations (rightfully so)
15 OtherClass<T,? super W> otherClass = (OtherClass<T,? super W>)getOtherClassForInterface(interfaceType);
16 if(null!=otherClass){
17 return otherClass;
18 }
19 }
20 }
21 return null;
22 }
23
24
25 public class OtherClass<T,V> {}
26
27 }
的問題是在第15行你必須轉換爲<? super W>
以獲得正確的類型。編譯器警告可以被抑制,但它是合理的嗎?有沒有一些情況下這個演員是不正確的?
類可能沒有這樣的方法,實際上使用T的任何超類,但代表一個類型本身,它聲稱提供有關超類型的信息。如果你看Class的getSuperclass()方法,它的返回類型是'Class super T>'。在這種情況下,getInterfaces()對我來說類似地返回似乎更合適。如果他們按照您的建議思考,那麼Class將永遠不會使用通過允許有界通配符訪問的任何方法,爲什麼Class會提供指定爲' super T>'的超類? –
sager
這可能是API設計者的錯誤。無論如何,我認爲這並不重要。 – irreputable
我已經添加了以這種方式使用Class的具體案例。它現在正在探索中。 – sager