2011-11-18 74 views
12

(要清理的問題,「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>以獲得正確的類型。編譯器警告可以被抑制,但它是合理的嗎?有沒有一些情況下這個演員是不正確的?

回答

5

你是對的,返回類型可能更具體。

但是,無論如何,Class<? super X>並不是非常有用。 Class<?>已經足夠用於大多數用途。

如果我們有一個聲明G<T>,爲G<? super X>是有用的,通常G應該有接受T方法。例如,List<T>add(T)。所以List<? super X>是很有用的,我們可以調用它add(x)xX型)

Class沒有這樣的方法。

你有一個令人信服的用例,你真的需要Class<? super ClassA>

+2

可能沒有這樣的方法,實際上使用T的任何超類,但代表一個類型本身,它聲稱提供有關超類型的信息。如果你看Class的getSuperclass()方法,它的返回類型是'Class '。在這種情況下,getInterfaces()對我來說類似地返回似乎更合適。如果他們按照您的建議思考,那麼Class將永遠不會使用通過允許有界通配符訪問的任何方法,爲什麼Class會提供指定爲''的超類? – sager

+0

這可能是API設計者的錯誤。無論如何,我認爲這並不重要。 – irreputable

+0

我已經添加了以這種方式使用Class的具體案例。它現在正在探索中。 – sager

0

再次,讓我們說,你有這樣的泛型方法聲明:

非數組例如

<T super Integer> void add(T number) // hypothetical! currently illegal in Java

而且你有這些變量聲明:

Integer anInteger Number aNumber Object anObject String aString

您的意圖與<T super Integer>(如果它是合法的)是它應該可以w add(anInteger)add(aNumber),當然還有add(anObject),但不是add(aString)。那麼,String是一個對象,所以add(aString)仍然可以編譯。

副本來源:Stack Overflow - Bounding generics with 'super' keyword

它幫助我。也可以幫助你:)

相關問題