2013-06-09 15 views
6

In Java, esiste un modo per separare le fasi che avvengono durante la creazione dell'oggetto:Creazione di un'istanza di oggetto non costruito

  • allocazione di memoria
  • costruzione oggetto

In altre parole, ci sono costrutti di alto livello (magari usando refection?) che mappano accuratamente le istruzioni bytecode new (allocazione di memoria) e invokespecial (costruzione di oggetti).

Nessun utilizzo particolare, più come una cosa di curiosità.

risposta

3

No, non ci sono API (riflessione o altro) per questo nel JDK. È comunque possibile manipolare il byte code stesso, in fase di esecuzione, utilizzando le librerie che lo fanno. Ad esempio, http://asm.ow2.org/

+0

anche con la manipolazione bytecode, non si ottiene l'accesso alla memoria prima che il costruttore jlo si sia chiuso normalmente. –

0

La JVM crea oggetti prima che vengano dati al costruttore; se un costruttore della classe derivata genera un'eccezione prima di concatenare al costruttore della classe base, mi aspetto che il metodo della classe derivata Finalize venga eseguito sull'oggetto senza che nessuna parte del costruttore base abbia mai eseguito.

+1

Umm, il costruttore della classe base non esegue * prima * il costruttore della classe derivata? –

+0

@OliCharlesworth: il costruttore della classe derivata deve iniziare con una chiamata al costruttore della classe base, ma è possibile che la valutazione dei parametri di quella chiamata non vada a buon fine (ad esempio se il costruttore derivato accetta un parametro 'foo' e chiama il costruttore di base con valore '1/foo', chiamare il costruttore derivato con un valore' foo' pari a zero genererebbe un'eccezione prima dell'esecuzione del costruttore base). – supercat

2
 sun.misc.Unsafe 

    /** Allocate an instance but do not run any constructor. 
     Initializes the class if it has not yet been. */ 
    public native Object allocateInstance(Class cls) 
     throws InstantiationException; 

    ---- 

    Field f = Unsafe.class.getDeclaredField("theUnsafe"); 
    f.setAccessible(true); 
    Unsafe unsafe = (Unsafe) f.get(null); 

    Integer integer = (Integer)unsafe.allocateInstance(Integer.class); 

    System.out.println(integer); // prints "0" 

non so come fare la seconda parte - invocare il costruttore su di esso.

+0

Interessante, grazie per aver segnalato questo pacchetto. Ho provato ad ottenere un riferimento sul costruttore predefinito "" usando Class.getDeclaredMethod(), ma non ho avuto tanta fortuna. – Nick

Problemi correlati