2011-01-14 10 views
5

Mi chiedevo se è possibile dichiarare un nuovo oggetto di un determinato tipo in Java, dato che ho rappresentato quel tipo come oggetto Class.Dichiarazione di oggetto Java dato il suo tipo/nome di classe come stringa

Per esempio, diciamo che ho

SomeClass obj1; 
Class c = obj1.getClass(); 

Ora vorrei prendere "c" e utilizzarlo per dichiarare un nuovo oggetto di quel tipo. Qualcosa in queste righe:

Class<c> my_new_var; 

tale che my_new_var sarebbe allora una variabile dello stesso tipo/classe obj1. Ciò è direttamente correlato, suppongo, alla possibilità di utilizzare un oggetto Class (o qualcosa relativo a quell'oggetto Class) come un tipo nella dichiarazione di una nuova variabile.

È possibile, o impossibile poiché Java è fortemente tipizzato?

Grazie in anticipo,

Bruno

+0

Tale inganno dinamica è ancora scoraggia in linguaggi dinamici. Perché pensi che sia una buona idea? – delnan

risposta

2
YourType newObject = c.newInstance(); 

Ma è necessario disporre di un costruttore no-arg. Altrimenti dovresti fare più riflessioni.

Si noti che non è necessario eseguire il cast se il proprio Class è parametrizzato. Se non lo è, come nel tuo codice, avresti bisogno di un cast.

Alla tua seconda domanda - no, non è possibile dichiarare una variabile di un tipo dinamico, perché sì, java è staticamente digitato. È necessario definire il tipo di una variabile in fase di compilazione. Nell'esempio precedente è possibile:

  • utilizzare Object, se non si conosce il tipo, perché è la superclasse di tutti gli oggetti.
  • uso di generici. Ad esempio (con gestione delle eccezioni omesso):

    public static <T> T createNewInstance(T exampleInstance) { 
        return (T) exampleInstance.getClass().newInstance(); 
    } 
    
+2

A condizione che la classe abbia un costruttore pubblico senza parametri. – biziclop

+0

Grazie Bozho. Capisco che c.newInstance() mi darà un nuovo oggetto dello stesso tipo di obj1; il problema è che quando dichiaro newObject, dovrei comunque dichiararlo come "YourType", che presumo di non sapere se non tramite "c". Idealmente, troverei che qualcosa come la classe può essere usata come un tipo quando dichiari una nuova variabile - tale che potrei fare Class newObject = c.newInstance(), ma capisco che questo potrebbe essere impossibile dato che Java è staticamente digitato. Ho ragione? Grazie ancora! – Bruno

+0

Come nel mio secondo esempio con 'T' (o' Object') è possibile rinviare la dichiarazione del tipo effettivo. Ma a un certo punto dovrai conoscere il tipo esatto. Se non ne hai bisogno (per chiamare i metodi su di esso), puoi semplicemente riferirlo come 'Oggetto' – Bozho

0

Ti piace questa:

Class c = Class.forName("com.xyzws.SomeClass"); 
Object a = c.newInstance(); 
1

Se si dispone di un costruttore di default:

SomeClass obj2 = (SomeClass) c.newInstance(); 
+0

Grazie Adbullah. Capisco la tua soluzione, ma nota che SomeClass, nel tuo comando, è esattamente il tipo/classe rappresentata da c, che in questo caso presumo di non sapere (tranne tramite c). Idealmente, quello che mi piacerebbe trovare è che qualcosa come la Classe può essere usato come un tipo quando si dichiara una nuova variabile, in modo che io possa fare qualcosa come Class newObject = c.newInstance(), ma capisco che questo potrebbe essere impossibile dal momento che Java è tipizzato staticamente. Ho ragione? Grazie ancora! – Bruno

+0

In qualsiasi linguaggio orientato agli oggetti devi conoscere il tipo di qualcosa prima di poter fare qualsiasi cosa con esso. In Java, questa può essere un'interfaccia o una classe base e puoi eseguire il cast su uno dei due. Senza sapere altro, è solo un oggetto e c'è ben poco che puoi fare con esso. –

0

my_new_var sarebbe di tipo Class<SomeClass>, che non è la stessa di obj1 che è di tipo SomeClass.

Tuttavia, my_new_var.newInstance() fornisce un nuovo oggetto che è dello stesso tipo di obj1.

0

Beh, si potrebbe fare questo:

SomeClass obj1 = ... 
Class<? extends SomeClass> c = obj1.getClass(); 
SomeClass obj2 = c.newInstance(); 

Questo richiede un costruttore no-arg su qualsiasi sottoclasse (se presente) di SomeClassobj1 in realtà è.

Tuttavia, questo funziona solo perché si conosce il tipo dell'oggetto Class in questione. Dato un arbitrario oggetto grezzo Class o Class<?>, non si saprebbe quale tipo di oggetto newInstance() restituirebbe e si sarebbe in grado di dichiarare tale istanza come Object.

0

per me questo ha funzionato:

Object innerObj = classObj.getClass().newInstance(); 
Problemi correlati