1. Panoramica
In questo breve tutorial, ci concentreremo sul tipo restituito per un costruttore in Java.
Innanzitutto, acquisiremo familiarità con il funzionamento dell'inizializzazione degli oggetti in Java e in JVM. Quindi, approfondiremo per vedere come l'inizializzazione e l'assegnazione degli oggetti funzionano dietro le quinte.
2. Inizializzazione dell'istanza
Cominciamo con una classe vuota:
public class Color {}
Qui creeremo un'istanza da questa classe e la assegneremo a una variabile:
Color color = new Color();
Dopo aver compilato questo semplice snippet Java, diamo un'occhiata al suo bytecode tramite il comando javap -c :
0: new #7 // class Color 3: dup 4: invokespecial #9 // Method Color."":()V 7: astore_1
Quando istanziamo un oggetto in Java, la JVM esegue le seguenti operazioni:
- Innanzitutto, trova un posto nel suo spazio di elaborazione per il nuovo oggetto.
- Quindi, la JVM esegue il processo di inizializzazione del sistema. In questo passaggio, crea l'oggetto nel suo stato predefinito. Il nuovo codice operativo nel bytecode è effettivamente responsabile di questo passaggio.
- Infine, inizializza l'oggetto con il costruttore e altri blocchi di inizializzazione. In questo caso, il codice operativo invokespecial chiama il costruttore.
Come mostrato sopra, la firma del metodo per il costruttore predefinito è:
Method Color."":()V
Il è il nome dei metodi di inizializzazione dell'istanza nella JVM . In questo caso, il fileè una funzione che:
- non accetta nulla come input (parentesi vuote dopo il nome del metodo)
- non restituisce nulla (V sta per void )
Pertanto, il tipo restituito di un costruttore in Java e JVM è nullo.
Dando un'altra occhiata al nostro semplice incarico:
Color color = new Color();
Ora che sappiamo che il costruttore restituisce void , vediamo come funziona l'assegnazione.
3. Come funziona l'assegnazione
JVM è una macchina virtuale basata su stack. Ogni stack è costituito da stack frame. In parole povere, ogni stack frame corrisponde a una chiamata al metodo. Infatti, JVM crea frame con una nuova chiamata al metodo e li distrugge quando finiscono il loro lavoro:

Ogni stack frame utilizza un array per memorizzare le variabili locali e uno stack di operandi per memorizzare i risultati parziali . Detto questo, diamo un'altra occhiata al bytecode:
0: new #7 // class Color 3: dup 4: invokespecial #9 // Method Color."":()V 7: astore_1
Ecco come funziona il compito:
- La nuova istruzione crea un'istanza di Color e inserisce il suo riferimento nello stack di operandi
- Il codice operativo dup duplica l'ultimo elemento nello stack di operandi
- Il invokespecial prende il riferimento duplicato e lo consuma per l'inizializzazione. Dopodiché, solo il riferimento originale rimane sullo stack degli operandi
- L'astore_1 memorizza il riferimento originale all'indice 1 della matrice variabili locali. Il prefisso "a" significa che l'elemento da memorizzare è un riferimento a un oggetto e "1" è l'indice dell'array
D'ora in poi, il secondo elemento (indice 1) nell'array delle variabili locali è un riferimento all'oggetto appena creato . Pertanto, non perdiamo il riferimento e l'assegnazione funziona effettivamente, anche quando il costruttore non restituisce nulla!
4. Conclusione
In questo breve tutorial, abbiamo appreso come la JVM crea e inizializza le nostre istanze di classe. Inoltre, abbiamo visto come l'inizializzazione dell'istanza funziona dietro le quinte.
Per una comprensione ancora più dettagliata della JVM, è sempre una buona idea controllare le sue specifiche.