2014-12-13 7 views
5

Questo codice:Perché la nuova Base() non può essere passata a <? estende Base>?

public class Base<E> { 
    static void main(String[] args) { 
     Base<? extends Base> compound = new Base<Base>(); 
     compound.method(new Base()); 
    }    //^error 
    void method(E e) { } 
} 

Dà tale errore di compilazione:

Error:(4, 17) java: method method in class Base<E> cannot be applied to given types; 
    required: capture#1 of ? extends Base 
    found: Base 
    reason: actual argument Base cannot be converted to capture#1 of ? extends Base by method invocation conversion 

Da quello che ho capito, E diventa ? extends Base, qualcosa che si estende Base. Quindi, perché non è possibile passare a new Base()?

risposta

7

Base<? extends Base> compound significa che compound è parametrizzato con qualche sottotipo di Base, ma non si sa quale. Se il tipo di parametro è sconosciuto, il compilatore non può verificare che new Base() corrisponda a quel tipo.

E fa diventare ? extends Base Si potrebbe pensare che il metodo avrebbe accettato qualsiasi sottotipo di Base, ma non è così. Accetta solo uno specifico sottotipo sconosciuto di Base.

Quindi non è possibile chiamare alcun metodo che utilizzi E come parametro, ma è possibile chiamare un metodo che restituisce E.

Permettere il tuo esempio per compilare porterebbe a errori di tipo-sicurezza come:

List<? extends Object> list = new ArrayList<String>(); 
list.add(new Object()); // Error - Can't add object to list of Strings. 
0

provare il seguente per definire il metodo come un generico:

<E> void method(E e) { } 

Nota la l'aggiunta del <E>.

Questo ha corretto l'errore di compilazione per me. Sebbene, mi sarei aspettato che il parametro che hai fornito a livello di classe fosse applicato.

+0

Con '' prima di metodo di qualsiasi oggetto può essere passato :) Ma, la mia domanda non è come farlo compilare. Sto chiedendo gentilmente una spiegazione del perché non compila :) –

Problemi correlati