Supponiamo Ho il seguente:Perché devo effettuare una chiamata generica in modo esplicito?
public <T extends Widget> List<T> first(T n) {
return first(n.getClass());
}
public <T extends Widget> List<T> first(Class<T> n) {
return new ArrayList<>();
}
Il compilatore si lamenta alla linea 3 con "incompatible types; required: java.util.List<T>; found: java.util.List<capture#1 of ? extends my.app.Widget>
". Che non capisco perché Mi sembra ragionevole che il tipo T
non possa mai cambiare in nessun caso se non un sottotipo.
Questo può essere risolto tramite casting esplicito, anche se non so perché è richiesto.
public <T extends Widget> List<T> first(T n) {
return (List<T>)first(n.getClass());
}
public <T extends Widget> List<T> first(Class<T> n) {
return new ArrayList<>();
}
Potrebbe essere un errore del compilatore?
Nota Sto usando JDK 1.7.0_15:
java version "1.7.0_15"
Java(TM) SE Runtime Environment (build 1.7.0_15-b03)
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)
Ho letto la tua risposta alcune volte e ho pensato di aver capito, ma non sono abbastanza sicuro ora. Diciamo che 'Circle' e' Square' sono sottoclassi di 'Widget'. Se chiamo 'first (Circle.class)' è possibile solo per un 'Elenco estende Circle> 'per tornare, cioè non posso' restituire il nuovo ArrayList 'come il compilatore non me lo consente. –
'Circle.class' è una costante di tempo di compilazione, non * è * la stessa cosa di' new Circle(). GetClass() 'che non viene risolto fino al runtime. Se hai chiamato 'first (Circle.class)' può restituire 'Lista' bene, ma non se aspetti fino al run time per scoprire il tipo effettivo. –
Affe
Aggiungendo alla mia confusione sono sorpreso che non posso anche fare 'Elenco y = primo (n.getClass());', anche se sicuramente la lista restituita può essere solo come hai detto tu, '? estende Widget' che, a quanto ho capito, questo elenco risultante può contenere solo 'Widget' o discendenti? –