2011-11-18 15 views
12

Neden java.lang.Class'ın getInterfaces() yöntemi, Sınıf <?> [] yerine ve Sınıf <? super T> []?

Sadece bir örnek olarak, aşağıdaki uygulamayı gözden geçirin (sorunun açıklığa kavuşturulması için, 'T' Sınıf bildirilen bir tür parametresi ifade eder):

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

çıkış biri ne beklenir :

TestClass$InterfaceA 
TestClass$InterfaceB 
TestClass$InterfaceC 

Yani, yukarıdaki örnekte dayanarak, derleyici interfaceâ karşılamak inci yaptığı tanıdığını görebilirsiniz Diğer tüm arayüzler gibi joker karakterinin e. Sezgisel

, ben güvenli olması için aşağıdaki beklenebilir, ama değil: imza o Class döndüren bulunduğunu belirtti

Class<? super ClassA>[] interfaces = ClassA.class.getInterfaces(); 

derleyici, bir uyarı verir; Bununla birlikte, sınıf için javadoc aşağıda belirtilmiştir: Bu amacın, bir sınıfını temsil

, dönüş değeri bir dizi sınıfı tarafından uygulanan tüm arayüzleri temsil içeren nesneler.

'Bu nesne' örneğimizde ClassA numaralı durumu belirtir.

ClassA.class.getInterfaces() 

sonra bildiğimiz, mantıksal olarak, döndürülen dizide her Class<?> ClassA süper türüne açıklamayı içerecek: Biz diyoruz eğer, bu ifadeye dayanarak.

Java Dil Başvurusu, Üçüncü Basım: From: referans ek noktası olarak

A sınıfı zorunlu olarak doğrudan süper sınıf ve doğrudan superinterfaces yaptığım arayüzleri uygular. Bu (çoklu) arabirim devralma, nesnelerin herhangi bir uygulamayı paylaşmadan (çoklu) ortak davranışları desteklemesine izin verir.

bu ve şartnamenin diğer kısımlarını okurken, bir sınıf T tarafından herhangi bir sınıf veya arabirim uygulanan veya exteneded sınırlarının <? super T> içine düşeceği düşünürdüm.

REDAKTE:

Benim soru için hiçbir somut neden olmadığı ileri sürülmüştür. Bir örnek verecek:

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 } 

sorun hattı Doğru tipini almak için <? super W> yayın yapmak için var 15. altındadır. Derleyici uyarısı bastırılabilir, ancak haklı mı? Bu yayınlamanın doğru olmadığı bir senaryo var mı?

cevap

5

Haklısınız, dönüş tipi daha açık olabilir.

Ancak, Class<? super X> yine de çok yararlı değil. Çoğu kullanım için Class<?> yeterlidir. biz faydalı olmak G<? super X> için bir bildiri G<T> varsa

, genellikle GT kabul yöntemleri olmalıdır. Örneğin, List<T>, add(T)'a sahiptir. Yani List<? super X> faydayı,

Class

tür yöntemleri yoktur (tip X olmanın x) Üzerinde add(x) çağırabilir.

Gerçekten Class<? super ClassA>'a gereksinim duyduğunuz ikna edici bir kullanım durumunuz var mı?

Yine
+2

10 Sınıf Sınıfının gerçekten de herhangi bir üst sınıfını kullanan bu tür yöntemlere sahip olmayabilir, ancak bir türün kendisini temsil ettiğini, süper türler hakkında bilgi sağladığını iddia eder. Class's getSuperclass() yöntemine bakarsanız, dönüş türü "Sınıf " şeklindedir. Bu durumda, getInterfaces() 'in bana benzer şekilde geri dönmesi daha da uygun görünmektedir. Düşündükçe, Class'ın sınırlandırılmış joker karakterine izin vererek bu yöntemlerden hiçbirini kullanamayacağını düşünürdüyse, Class neden "" olarak tanımlanmış bir süper sınıf sağlar? – sager

+0

Bu, muhtemelen API tasarımcısı tarafından bir hata. Zaten bunun önemli olmadığını tartışıyorum. – irreputable

+0

Bu şekilde Class kullanmanın somut bir örneğini ekledim. Artık görevde kendisi var. – sager

0

, diyelim ki bu jenerik yöntem beyanı olduğunu varsayalım:

bir dizi olmayan örnek

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

Ve bu değişken bildirimleri var:

Integer anInteger Number aNumber Object anObject String aString

<T super Integer> ile olan niyetiniz (eğer yasal ise) add(anInteger) ve add(aNumber) ve tabiki add(anObject), ancak add(aString). Dize, bir Nesne, bu nedenle add(aString) yine de derleyecekti. Stack Overflow - Bounding generics with 'super' keyword

Bu bana yardımcı oldu: den

kopyası.

İlgili konular