(Per chiarire la questione, 'T' si riferisce a un parametro di tipo dichiarata in classe)Perché il metodo getInterfaces() di java.lang.Class restituisce la Classe <?> [] e non la Classe <? super T> []?
A titolo di esempio, consulta la seguente applicazione:
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());
}
}
}
L'uscita è quello che ci si aspetterebbe :
TestClass$InterfaceA
TestClass$InterfaceB
TestClass$InterfaceC
Quindi, sulla base di questo esempio di cui sopra, possiamo vedere che il compilatore riconosce che InterfaceA fa incontrano ° I limiti del carattere jolly, come fanno tutte le altre interfacce.
Intuitivamente, mi aspetto che la segue per essere al sicuro, ma non lo è:
Class<? super ClassA>[] interfaces = ClassA.class.getInterfaces();
Il compilatore dà un avvertimento, perché la firma dice che restituisce classe; tuttavia, il javadoc per Classe membri le seguenti:
Se questo oggetto rappresenta una classe, il valore restituito è un array contenenti oggetti che rappresentano tutte le interfacce implementate dalla classe .
'Questo oggetto' si riferisce nel nostro caso a ClassA
. Sulla base di questa affermazione, se chiamiamo:
ClassA.class.getInterfaces()
allora sappiamo, logicamente, che ogni Class<?>
nella matrice restituita conterrà un riferimento a un super tipo di ClassA
.
Come un ulteriore punto di riferimento:
Dal Java Language Reference, Third Edition:
Una classe implementa necessariamente tutte le interfacce che i suoi diretti superclassi e superinterfacce dirette fanno. Questa (più) interfaccia ereditaria consente agli oggetti di supportare (più) comportamenti comuni senza condividere alcuna implementazione.
La lettura di questa e di altre parti della specifica, penserei che qualsiasi classe o interfaccia implementata o exteneded da una classe T
cadrebbero nella i limiti <? super T>
.
Modificato:
È stato suggerito che non v'è alcuna ragione concreta per la mia domanda. Fornirò un esempio:
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 }
Il problema è alla riga 15. Si deve lanciare per <? super W>
per ottenere il tipo corretto. L'avviso del compilatore può essere soppresso, ma è giustificato? C'è qualche scenario in cui questo cast non è vero?
La classe potrebbe non avere tali metodi che effettivamente usano una superclasse di T, ma, rappresentando un tipo stesso, afferma di fornire informazioni sui super-tipi. Se si guarda il metodo getSuperclass() di Class, il suo tipo restituito è 'Classe super T>'. Stando così le cose, sembra ancora più appropriato che getInterfaces() ritorni in modo simile a me. Se pensassero, come lei suggerisce, quella Classe non userebbe mai nessuno di quei metodi accessibili accettando il carattere jolly limitato, perché Class fornirebbe una superclasse che viene specificata come ' super T>'? –
sager
Probabilmente è un errore del progettista API. Sto sostenendo che non importa comunque. – irreputable
Ho aggiunto un caso concreto di utilizzare Class in questo modo. È nella ricerca stessa ora. – sager