2013-05-13 6 views
6

Sto chiamando un metodo da una libreria con questa firma:Come posso restituire un elenco di un certo tipo quando si chiama un metodo generico che accetta una classe <T> e restituisce una T?

public <T> T get(Class<T> c) 

e mi piacerebbe ottenere un List<MyClass> come valore di ritorno. Ma chiamando in questo modo non viene compilato ("Non è possibile selezionare dal tipo parametrico"):

List<MyClass> myClasses = get(List<MyClass>.class); 

Questo compila, ma dà un avvertimento:

List<MyClass> myClasses = get(List.class); 

L'avviso dice "Assegnazione Unchecked". Come posso evitare questo avvertimento ed evitare di trasmettere la mia lista?

risposta

3

Qui si utilizzano i generici, quindi il tipo sottostante dell'elemento nell'elenco è stato cancellato in fase di esecuzione e il compilatore sa che non è in grado di controllarlo al momento della compilazione, quindi l'avviso. Se si utilizza un tipo generico qui non sarà possibile evitare l'avviso. Puoi sopprimerlo se sai per certo che il cast che stai facendo non porterà a un'eccezione.

@SuppressWarnings("unchecked") 
1

Nota: inserisco questo più come un punto di interesse che come una risposta consigliato. In genere stai meglio semplicemente sopprimendo gli avvertimenti.

Se davvero odio sopprimere avvertimenti, ma odi anche vedere gli avvertimenti, c'è un hacky alternativa alla risposta accettata. È possibile creare un'istanza di un oggetto archetipo, ad esempio ArrayList<MyClass>, e quindi passare archetype.getClass() nel metodo generico anziché List.class come nell'esempio e nella risposta accettata.

Questo sarà simile:

ArrayList<MyClass> archetype = new ArrayList<>(); 
List<MyClass> myClasses = get(archetype.getClass()); 

Un'ovvia svantaggio è il costo inutilmente un'istanza dell'oggetto archetipo, ma questo può essere mitigato alquanto rendendo un'istanza statica. Uno svantaggio più grande, a mio avviso, è che devi usare una classe concreta come il tuo archetipo, che può essere inutilmente limitante.

Problemi correlati