JavaRush /Java Blog /Random-IT /Differenze tra costruttori e metodi ordinari.
fog
Livello 18

Differenze tra costruttori e metodi ordinari.

Pubblicato nel gruppo Random-IT
Un costruttore è un metodo speciale destinato a impostare inizialmente i valori dei campi di un oggetto. A prima vista, i costruttori di oggetti non differiscono molto dai normali metodi di oggetti. E infatti, all'interno del costruttore possiamo fare tutto ciò che possiamo fare nei normali metodi degli oggetti: inviare testo alla console, accedere a tutti i campi e metodi del nuovo oggetto, lanciare eccezioni e così via. Proprio come i metodi normali, i costruttori possono avere argomenti. Proprio come i metodi sovraccaricati, possono esserci più costruttori con firme diverse. Proprio come i metodi generici, i costruttori possono essere parametrizzati da variabili di tipo. Anche se esaminiamo il bytecode generato dal compilatore, nel punto in cui dovrebbe esserci una chiamata al costruttore, troveremo una chiamata a qualche metodo il cui nome non è diverso dalla chiamata ad altri metodi <init>di l'oggetto. E dopo aver trovato il bytecode di questo metodo, scopriremo che contiene il risultato della compilazione del nostro costruttore. Sembra che non ci siano molte differenze rispetto ai metodi convenzionali, ma esistono, e sono piuttosto significative. Per prima cosa, scopriamolo, perché abbiamo effettivamente bisogno dei costruttori? Per archiviare ed elaborare qualsiasi dato, sia esso tipo primitivo, array o oggetto, abbiamo bisogno di una certa quantità di memoria. Può trattarsi di registri del processore, spazio dello stack o una parte di spazio allocata nella sezione dei dati di processo o in una parte di memoria allocata dinamicamente (heap). In molti linguaggi di programmazione, per motivi di accelerazione, quando un programma richiede una nuova porzione di memoria, la memoria viene assegnata al programma non cancellata e potrebbe contenere dati arbitrari archiviati in precedenza in questa cella di memoria. La preparazione e la scrittura dei valori necessari in un pezzo di memoria del genere, in modo che alla fine ci fosse una struttura dati significativa, ricadeva interamente sulle spalle del programmatore. Abbastanza naturalmente, i programmatori volevano semplificarsi la vita e scrivevano routine per inizializzare (cioè impostare valori iniziali) per le strutture dati utilizzate di frequente. Tali routine venivano utilizzate quasi costantemente, quindi i creatori del linguaggio Java decisero di rendere obbligatorio chiamare tali routine di inizializzazione durante la creazione di oggetti e le chiamarono costruttori . Quando viene creato un nuovo oggetto in Java, accade quanto segue: Innanzitutto, il gestore della memoria Java alloca la quantità di memoria necessaria per ospitare l'oggetto. In questo caso non vengono presi in considerazione solo i campi dichiarati direttamente nella classe dell'oggetto creato, ma anche i campi dichiarati in tutti gli antenati di questa classe. Inoltre, questo volume include spazio per posizionare le strutture utilizzate dalla macchina Java per esigenze interne. Tutti i campi di tale "spazio vuoto" vengono automaticamente impostati sui valori predefiniti: nullper i tipi di riferimento, 0per i numeri e falseperboolean. Successivamente viene chiamato automaticamente il costruttore della classe, il cui compito è impostare i valori iniziali dei campi dell’oggetto. Mentre in un metodo normale la prima istruzione può essere qualsiasi cosa, il costruttore ha molta meno libertà. La prima istruzione di un costruttore deve essere una chiamata esplicita a un altro costruttore della stessa classe oppure una chiamata esplicita o implicita a un costruttore di una classe genitore. Le chiamate esplicite ai costruttori della stessa classe vengono effettuate utilizzando una parola chiave thisseguita da un insieme di argomenti racchiusi tra parentesi. La chiamata esplicita al costruttore di una classe genitore viene eseguita esattamente nello stesso modo, ma viene utilizzata la parola chiave super. Negli argomenti di una chiamata esplicita al costruttore della stessa classe o della classe madre, non è possibile accedere ai campi e ai metodi dell'oggetto, né utilizzare le parole chiave thise super, poiché una chiamata esplicita al costruttore introduce un contesto statico. Per chiamare implicitamente il costruttore di una classe genitore non è necessario scrivere nulla, ma viene chiamato implicitamente il costruttore predefinito, che deve esistere ed essere visibile alla classe corrente. Allo stesso tempo, va tenuto presente che se la catena di chiamate dei costruttori genitori viene interrotta prima che il costruttore della classe Objectsituato nella parte superiore della catena completi con successo il suo lavoro, l'oggetto non sarà finalizzabile, cioè il metodo finalize()di un tale oggetto non verrà mai chiamato. Una volta completato il costruttore della classe padre, il controllo viene trasferito implicitamente ai blocchi inizializzatori di istanza e agli inizializzatori di campi di istanza della classe corrente. Gli inizializzatori vengono eseguiti nell'ordine in cui appaiono nel testo del programma. Solo dopo che gli inizializzatori hanno completato il loro lavoro il controllo viene trasferito al resto del costruttore. Le restanti caratteristiche dei costruttori si riferiscono al modello di memoria Java. Se una classe, o uno dei suoi antenati, sovrascrive il metodo finalize(), il completamento del costruttore avverrà prima ( accade prima ) dell'esecuzione del metodo finalize(). Se qualche thread ha visto un riferimento a un oggetto dopo il completamento del costruttore, è garantito che questo thread vedrà i finalcampi dell'oggetto correttamente inizializzati, la cui inizializzazione è avvenuta prima del completamento del costruttore.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION