2012-05-31 13 views
8

Sono bloccato. Venendo dal C++ pensavo che avrebbe funzionato semplicemente, ma non è così. Puoi per favore darmi un consiglio? Cercherò di non finire con tipo di metodo di creazione in ciascuna classe utilizzata per T.Istanziare il tipo generico in java

public class A<T>{ 

    private T t_; 

    public A(){ 
     t_ = new T(); //error 
    } 

} 

Anche io non voglio avere costruttore di assomigliare: A (Classe classT) {... Idealmente mi piacerebbe avere qualcosa come questo codice C++.

template<class T> 
class A{ 
private: 
    T t_; 

public: 
    A(){} 

}; 

Grazie per l'aiuto.

+0

possibile duplicato del [Crea istanza di tipo generico in Java?] (http://stackoverflow.com/questions/75175/create-instance-of-generic-type-in-java) – pingw33n

+0

hai ragione. completamente trascurato che – nux

risposta

5

Mi dispiace disapointarti ma questo è semplicemente impossibile in Java senza costruttori.

Java butta via le informazioni generiche in fase di esecuzione (vedi tipo di cancellazione)

11

Oltre alla questione della cancellazione del tipo - che rende questo impossibile in ogni caso - semplicemente non si può garantire che T ha un esposto, costruttore no-argument!

La soluzione tradizionale consiste nel passare gli oggetti factory che forniscono metodi che possono essere utilizzati per ottenere gli oggetti T. Un esempio semplice sarebbe

interface Factory<T> { 
    T create(); 
} 

e poi la classe può ottenere un Factory<T> e chiamare create() su di esso per ottenere più T s. Esempi più sofisticati potrebbero richiedere argomenti aggiuntivi per un metodo create, ad esempio, o sovraccarichi.

Meno soluzioni alternative includono la riflessione esplicita, passando intorno agli oggetti Class<T>. Ad esempio, ArrayList.class.newInstance() restituisce un raw appena costruito ArrayList. È necessario passare esplicitamente attorno all'oggetto Class e l'approccio basato sulla riflessione è più lento di un normale costruttore o di un oggetto factory (anche se la velocità di riflessione è migliorata di recente). Dipende anche dalla classe che espone un costruttore no-arg, il che non è sempre il caso. Può essere fatto funzionare, ma non è mai quello che chiamerei "piacevole".

(che ha detto, per riferimento, vi sono indicazioni che la situazione potrebbe cambiare un po 'in Java 8 con Project Lambda e gli amici.)

+0

Grazie per il suggerimento. Sembra che devo fare così: / – nux

0

provare questo:

private <E extends ISomething> E createInstance(Class<E> clazz) { 
     E ret; 
     try { 
      ret = clazz.newInstance(); 
      ret.setSomething(something); 

     } catch (InstantiationException e) { 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 
     return ret; 
    }