2009-08-05 15 views
8

Se si dispone di un metodo con la firma:Java classe generized riferimento

Class<? extends List<String>> getObjectType() 
{ 
     return ?????; 
} 

Come si restituiscono una versione corretta generica della classe List?

return List.class; //errors 
return List<String>.class; //errors 
return List.class<String>; //errors 

qual è la sintassi corretta per gestire questa situazione?

risposta

9

È necessario eseguire il cast esplicito per il tipo restituito. Questo funziona:

return (Class<? extends List<String>>) List.class; 

Sì, sembra solo sbagliato. Questo è solo uno dei tanti motivi per cui il sistema generico di Java è un casino.

+0

Interessante, me facendo il suo suggerimento si avvicina come eclissi smette di lamentarsi. ma quando vado a compilare la classe con il compilatore java ottengo "tipi inconverti trovati: java.lang.Class richiesto: java.lang.Class > " –

+0

Dispari, funziona per me all'interno di Eclipse, ma non quando è compilato sulla riga di comando. Non l'ho mai visto prima. –

+0

Con l'opzione -nowarn funziona per il caso di restituire someList.getClass(), ma continuo a ricevere lo stesso errore che si prova quando si prova con List.class. –

2

È necessario restituire la classe di qualcosa che si estende List<String>. ArrayList<String> è un esempio. Si può provare:

ArrayList<String> myList = new ArrayList<String>(); 
... 
return (Class<? extends List<String>>)myList.getClass(); 
+1

È necessario il cast esplicito. Il metodo generale getClass restituisce il tipo Classe . –

+0

@ John: Grazie per averlo indicato. Ho controllato, e questo è davvero il caso. Ho aggiornato il mio esempio per includere il cast. –

5

Dal libro "Effective Java" (seconda edizione, pag 137): "Non usare tipi jolly come tipi di ritorno Piuttosto che garantisce una maggiore flessibilità per gli utenti, che li costringerebbe a. usa i caratteri jolly nel loro codice cliente. "

Detto questo, per lanciare, è necessario creare una variabile temporanea:

@SuppressWarnings("unchecked") 
Class<? extends List<String>> result = ....; 
return result; 

Questo funziona perché si può avere annotazioni sulle assegnazioni. Non funziona su return stesso. Si potrebbe anche aggiungere questo al metodo, ma ciò nasconderebbe anche altri problemi.

+1

Per me non ha solo avvisato, in realtà ha prodotto un errore di compilazione fino a quando ho aggiunto il cast. –

+0

corretto. "Elenco" e "Elenco <...>" sono tipi completamente diversi (proprio come String e Integer), quindi è necessario il cast. Ma il cast causerà un avvertimento e dovrai sopprimerlo. –

0

List.class e List <String> .class: in tutti questi casi è necessario il casting. Davvero avete bisogno di un tipo, che ha List <String> in fase di esecuzione, somethig come questo:

interface StringList extends List<String> {}; 

public Class<? extends List<String>> getObjectType() { 
    return StringList.class; 
} 
Problemi correlati