Sei sulla pagina 1di 7

CP pensareprogettareprogrammare n.

143 febbraio 2004

Il processo di inizializzazione in Java


parte 2

di Guido Anselmi
Vediamo in questo articolo la costruzione delle istanze di una classe ed un loro particolare uso attivo

Guido Anselmi Laureato in Ingegneria Informatica, si interessa da molti anni di programmazione Object Oriented. Attualmente si occupa di formazione ` Java e di qualita del software presso una ` importante societa nanziaria di Milano.

pubblicato su WWW.INFOMEDIA.IT stampa digitale da Lulu Enterprises Inc. stores.lulu.com/infomedia


Infomedia
` Infomedia e limpresa editoriale che da quasi venti anni ha raccolto la voce dei programmatori, dei sistemisti, dei professionisti, degli studenti, dei ricercatori e dei professori dinformatica italiani. Sono pi` di 800 gli autori che hanno realizzato per le teu state Computer Programming, Dev, Login, Visual Basic Journal e Java Journal, molte migliaia di articoli tecnici, presentazioni di prodotti, tecnologie, protocolli, strumenti di lavoro, tecniche di sviluppo e semplici trucchi e stratagemmi. Oltre 6 milioni di copie distribuite, trentamila pagine stampate, fanno di questa impresa la pi` grande ed u inuente realt` delleditoria specializzata nel campo della a programmazione e della sistemistica. In tutti questi anni le riviste Infomedia hanno vissuto della passione di quanti vedono nella programmazione non solo la propria professione ma unattivit` vitale e un vero a divertimento. ` Nel 2009, Infomedia e cambiata radicalmente adottando ` un nuovo modello aziendale ed editoriale e si e organizzata attorno ad una idea di Impresa Sociale di Comunit` , a partecipata da programmatori e sistemisti, separando le attivit` di gestione dellinformazione gestite da un board a comunitario professionale e quelle di produzione gesti` te da una impresa strumentale. Questo assetto e in linea con le migliori esperienze internazionali e rende Infomedia ancora di pi` parte della Comunit` nazionale degli u a sviluppatori di software. ` Infomedia e media-partner di manifestazioni ed eventi in ambito informatico, collabora con molti dei pi` imporu tanti editori informatici italiani come partner editoriale e fornitore di servizi di localizzazione in italiano di testi in lingua inglese.

Limpaginazione automatica di questa rivista e realizzata al ` 100% con strumenti Open Source usando OpenOffice, Emacs, BHL, LaTeX, Gimp, Inkscape e i linguaggi Lisp, Python e BASH

For copyright information about the contents of Computer Programming, please see the section Copyright at the end of each article if exists, otherwise ask authors. Infomedia contents is 2004 Infomedia and released as Creative Commons 2.5 BY-NC-ND. Turing Club content is 2004 Turing Club released as Creative Commons 2.5 BY-ND. Le informazioni di copyright sul contenuto di Computer Programming sono riportate nella sezione Copyright alla ne di ciascun articolo o vanno richieste direttamente agli autori. Il contenuto Infomedia e 2004 Infome` dia e rilasciato con Licenza Creative Commons 2.5 BYNC-ND. Il contenuto Turing Club e 2004 Turing Club ` e rilasciato con Licenza Creative Commons 2.5 BY-ND. Si applicano tutte le norme di tutela dei marchi e dei segni distintivi. ` E in ogni caso ammessa la riproduzione parziale o totale dei testi e delle immagini per scopo didattico purch e vengano integralmente citati gli autori e la completa identicazione della testata. Manoscritti e foto originali, anche se non pubblicati, non si restituiscono. Contenuto pubblicitario inferiore al 45%. La biograa dellautore riportata nellarticolo e sul sito www.infomedia.it e di norma quella disponibi` le nella stampa dellarticolo o aggiornata a cura dellautore stesso. Per aggiornarla scrivere a info@infomedia.it o farlo in autonomia allindirizzo http://mags.programmers.net/moduli/biograa

PROGRAMMING

Il processo di inizializzazione in Java


Vediamo in questo articolo la costruzione delle istanze di una classe ed un loro particolare uso attivo
di Guido Anselmi

Seconda Parte
stato iniziale invalido (ma pur sempre prevedibile). Nel prosieguo dellarticolo andremo ad esaminare nei dettagli gli strumenti offerti da Java per linizializzazione degli oggetti, e precisamente: 1) Costruttori 2) Instance variable initilializer 3) Instance block initializer Tutti e tre questi strumenti possono essere utilizzati al fine di assegnare alle variabili distanza il valore desiderato. Si noti bene che, ancor prima dellesecuzione del costruttore o degli initializer, la JVM assegna a qualunque variabile distanza un valore di default, il cui valore lo stesso di quello visto per le variabili di classe e riportato per comodit in Tabella 1.

n oggetto una zona di memoria associata al codice che lo manipola, ed dotato di uno stato interno che pu cambiare durante il suo ciclo di vita. Allinizio della vita di ogni oggetto, la JVM alloca sullo heap lo spazio necessario a contenere limmagine delloggetto stesso, della quale fanno parte le variabili distanza. Non appena allocata, i dati contenuti in questa zona di memoria sullo heap non sono tuttavia prevedibili. Se fosse consentito ai programmatori di accedere alla memoria in questo stato, il comportamento dei programmi diverrebbe non prevedibile. Per scongiurare questo scenario, Java assicura che la memoria sia sempre inizializzata, al peggio a valori di default, prima di poter essere acceduta dal codice. Questo comportamento un fondamentale ausilio ai programmatori, poich storicamente dati non inizializzati sono fonte di errori, spesso critici. Questo ad esempio un rischio comune in C, ove non esiste un meccanismo predefinito di inizializzazione. In tale linguaggio i programmatori sono costretti ad inizializzare esplicitamente i dati dopo che la memoria ad essi associata stata allocata e prima di usarli. In Java, al contrario, i meccanismi predefiniti di inizializzazione forniscono un grande aiuto nellevitare la creazione di oggetti con stato iniziale invalido. Questo tuttavia non deve lasciar pensare che la JVM faccia tutto da sola, sollevando completamente il programmatore da ogni responsabilit nellinizializzazione dei propri oggetti. Al contrario, allo sviluppatore di applicazioni Java richiesta in tale fase grande accortezza, unita ad una perfetta padronanza dei meccanismi predefiniti di inizializzazione, al fine di evitare utilizzi impropri di questi ultimi, che possono portare comunque ad uno

Costruttori
Sono lo strumento principale di inizializzazione. Al pari dei normali metodi possono avere un modificatore daccesso, ma nessun costruttore, nemmeno quando dichiarato come public, viene ereditato dalle sottoclassi. Il modificatore daccesso per i costruttori inteso solo al fine di stabilire chi abbia i diritti di costruire unistanza di una determinata classe. I costruttori devono obbligatoriamente avere lo stesso nome della classe e nessun tipo di ritorno. Le specifiche del linguaggio, tuttavia, non vietano di dichiarare normali

TABELLA 1
Tipo int long short char byte boolean reference float double

Valori di default delle variabili d'istanza

Guido Anselmi

ganselmi@infomedia.it

Laureato in Ingegneria Informatica, si interessa da molti anni di programmazione Object Oriented. Attualmente si occupa di formazione Java e di qualit del software presso una importante societ finanziaria di Milano.

Valore default 0 0L 0 '\u0000' 0 false null 0.0f 0.0d

Computer Programming n. 143 - Febbraio 2005

39

java
metodi con il nome della classe, come ad esempio avviene nel frammento di codice seguente:
public class BadName { public void BadName(){/* codice del metodo */} }

scopi e possibilit dimpiego pi ampie rispetto agli instance variable initializer. In particolare essi si rivelano una valida alternativa ai primi in due situazioni particolari, e precisamente: quando il codice di inizializzazione deve avere la possibilit di gestire una eccezione; quando linizializzazione necessita di un codice pi complesso di un assegnamento ad una espressione. Naturalmente si pu obiettare che entrambi i compiti appena indicati possono essere svolti egregiamente da un costruttore, senza la necessit di utilizzare un instance initialization block. Lutilit effettiva di tale strumento si manifesta principalmente in classi che dispongono di diversi costruttori, ciascuno dei quali debba svolgere un compito comune. Per far questo si pu realizzare un copia e incolla della parte di codice comune in ogni costruttore, oppure inserirla in un metodo privato della stessa classe da invocare da ciascuno dei costruttori. Entrambe le soluzioni lasciano per la porta aperta ad errori dovuti a dimenticanze o ad errori di copia. Al contrario, come sar pi chiaro alla fine dellarticolo, se il codice in questione viene inserito in un instance initialization block, esso viene automaticamente eseguito dalla JVM, qualunque costruttore sia stato invocato. Altro ambito nel quale lutilizzo di questi initializer si rivela prezioso allinterno di inner class anonime. Tali classi, per loro stessa definizione, non possono dichiarare alcun costruttore e quindi un blocco di inizializzazione pu essere proficuamente impiegato per assolvere a compiti complessi di inizializzazione. Gli instance initialization block possono sollevare delle eccezioni, ma solo quelle previste da tutti i costruttori della classe. Questa regola rilassata per le classi anonime, entro le quali i blocchi di inizializzazione distanza possono sollevare qualunque eccezione. Entrambi i due tipi di initializer devono soggiacere alla regola per cui non possono riferirsi a nessuna variabile dichiarata testualmente dopo la variabile inizializzata. Ad esempio il seguente codice non compila:
class WrongInitializer { private int x = y*2; //questa linea non compila private int y = 5 ; }

Bench perfettamente legale, tale codice decisamente da sconsigliare in quanto poco chiaro, oltre che non rispettoso delle convenzioni di naming del linguaggio Java. Secondo tali convenzioni, infatti, tutti i nomi dei metodi dovrebbero essere dei verbi, a rappresentare chiaramente lazione che sono chiamati a compiere. Tali nomi, inoltre, dovrebbero sempre iniziare con la lettera minuscola. Come noto, il corpo del costruttore il luogo designato a svolgere la maggior parte del lavoro di inizializzazione di un oggetto. Tipicamente i programmatori inseriscono al suo interno la gran parte del codice atto a fornire loggetto di uno stato iniziale valido, alloccorrenza invocando altri metodi. Si osservi come tutte le classi abbiano sempre almeno un costruttore. Se infatti si dichiara una classe sprovvista di costruttori, la JVM ne costruir automaticamente uno, il cosiddetto costruttore di default. Tale costruttore avr una lista di parametri vuota ed un corpo senza alcuna istruzione. La sua importanza sar pi chiara nel prosieguo dellarticolo.

Initializer
Come detto in precedenza, Java offre due distinti tipi di initializer distanza, gli instance variable initializer e gli instance initialization block. Nei primi, a differenza dei costruttori, nel corpo dei quali il programmatore pu inserire qualunque istruzione, si ha disposizione solamente la possibilit di assegnare una espressione Java ad una variabile distanza. La forma di qualunque instance variable initializer la seguente:
class Aclass { private int i = 10; }

In seguito alla sua esecuzione, tutte le istanze di Aclass avranno il field i inizializzato al valore dieci. Sul lato destro di un instance variable initializer possibile utilizzare qualunque espressione Java, inclusa linvocazione di un metodo. La seconda forma di initializer, gli instance initialization block sono stati introdotti nel linguaggio a partire dalla versione 1.1 del JDK. La loro sintassi la seguente:
class Aclass { { private int i = 10; } }

Se tale codice fosse lecito, la variabile x riceverebbe il valore zero (poich y sarebbe ancora al valore di default) e non dieci come atteso. Il compilatore di grande aiuto in situazioni simili, tuttavia non in grado di evitare tutti i problemi di questo genere. Si consideri ad esempio il seguente codice:
class CompilableWrongInitializer {

Con tale codice si ottiene lo stesso identico risultato dellesempio precedente, ma tale forma di initializer ha

private int x = getDoubleY();//ora compila, ma non d il risultato atteso

40

Computer Programming n. 143 - Febbraio 2005

PROGRAMMING
oggetto pienamente e correttamente inizializzato. Qualunque oggetto, infatti, incorpora non solo le variabili dichiarate nella sua classe, ma anche tutte quelle ereditate dalle superclassi che, prima di potere essere utilizzate, devono essere a loro volta inizializzate. Nel momento in cui la JVM si trova a dover costruire un nuovo oggetto, essa alloca sullo heap spazio sufficiente a contenere tutte le variabili facenti parte dellimmagine di quelloggetto, incluse naturalmente tutte quelle ereditate e non dichiarate esplicitamente nella classe di appartenenza. Stranamente, pur non essendo realmente ereditate, anche le variabili dichiarate come private in una superclasse vanno a far parte dellimmagine di unistanza di una sottoclasse. Ma come pu la JVM assicurarsi che tutte queste variabili ereditate siano correttamente inizializzate nellimmagine delle sottoclassi? La risposta al quesito quasi banale: invocando i costruttori e gli initializer distanza delle superclassi. Meno banale invece il meccanismo con cui questo avviene, intimamente legato alla struttura dei metodi di inizializzazione distanza. Tali metodi sono costruiti direttamente dal compilatore, che ne crea uno per ogni costruttore dichiarato in qualsiasi classe. Poich tutte le classi hanno almeno un costruttore, al peggio quello di default, se ne deduce che ogni classe possiede sempre almeno un metodo dinizializzazione distanza, a differenza del metodo di inizializzazione di classe che, come visto nel precedente articolo, non sempre presente.

In un costruttore possibile invocare esplicitamente un altro costruttore dichiarato nella stessa classe oppure nella superclasse diretta. Queste chiamate sono tuttavia soggette a restrizioni abbastanza stringenti. Innanzitutto esse sono mutuamente esclusive: se presente linvocazione a this() non consentita la chiamata a super(), e viceversa. Inoltre, se presenti, entrambe devono obbligatoriamente essere la prima istruzione del costruttore. Altro aspetto molto importante che le chiamate ad un altro costruttore non possono essere racchiuse in un blocco try/catch. Ad esempio un codice come il seguente non sarebbe legale:
class Aclass{ public Aclass(){ try { Aclass(1) }catch (Exception e){//ignora} } public Aclass(int i) throws Exception{ } }

Il motivo di questa ulteriore limitazione risiede nella volont dei progettisti del linguaggio di impedire la creazione di oggetti con stato iniziale invalido. Se infatti un codice come quello dellesempio fosse lecito, si potrebbe continuare la creazione di unistanza di Aclass, ignorando completamente eventuali errori occorsi nel corpo del costruttore invocato. Tali errori potrebbero ad esempio aver causato la mancata inizializzazione di field o strutture dati facenti parte dello stato delloggetto ed il loro utilizzo sarebbe molto pericoloso e potenzialmente fonte di errori.

RIQUADRO 1

Chiamate tra costruttori

Struttura degli InstanceInitializationMethod


I metodi di inizializzazione costruiti dal compilatore hanno tipo di ritorno void e possiedono una lista di parametri identica a quella del costruttore corrispondente, con in pi un reference allo stesso oggetto. Tale reference, il cosiddetto hidden this, viene aggiunto dal compilatore per tutti i metodi distanza ed il mezzo tramite cui tutti i metodi possono accedere i dati distanza. Allinterno di un InstanceInitializationMethod il compilatore inserisce codice per tre attivit ben differenziate: 1) invocazione di un altro metodo dinizializzazione distanza; 2) esecuzione di tutti gli instance initializer dichiarati nella classe di appartenenza; 3) esecuzione del corpo del costruttore corrispondente; Cominciamo ad analizzare il primo punto. Il metodo dinizializzazione invocato in tale fase dipende dalle scelte del programmatore. Nel corpo di un costruttore, infatti, possibile invocare esplicitamente un altro costruttore della stessa classe, con la sintassi this (arglist), o della superclasse diretta, tramite la sintassi super (arglist). Si veda il Riquadro 1 per maggiori det-

private int y = 5 ; private int getDoubleY(){ return y*2;} }

La classe in esame non viola la regola appena descritta ed il compilatore non solleva quindi alcuna obiezione. Tale codice tuttavia pu essere fonte di errori insidiosi, in quanto la variabile x destinata a ricevere il valore iniziale zero per qualunque istanza di tale classe, e non il valore atteso dal programmatore. Infatti al momento della esecuzione del metodo getDoubleY(), linitializer di y non stato ancora eseguito e tale variabile si trova ancora al valore di default. Quello che non ancora chiaro alla luce di quanto finora detto, il momento in cui un initializer distanza viene invocato, e precisamente se prima o dopo di un qualsiasi costruttore. La risposta a questa domanda verr data nel paragrafo successivo.

Metodi di inizializzazione distanza ed ereditariet


Come visto per le variabili di classe, anche nel caso degli oggetti il processo di inizializzazione comporta molto lavoro da parte della JVM. Lassegnazione del valore proprio alle variabili distanza, tramite costruttore o initializer, non sufficiente per ottenere un

Computer Programming n. 143 - Febbraio 2005

41

java
tagli. Se presente la chiamata esplicita ad un altro costruttore, la JVM si limiter ad invocare il metodo dinizializzazione distanza corrispondente a tale costruttore. Se invece questa chiamata non presente, il compilatore aggiunger come prima istruzione una invocazione al metodo dinizializzazione distanza senza argomenti della superclasse diretta. Naturalmente questo un processo che si ripete in tutte le superclassi incontrate lungo il cammino di derivazione, fino ad Object. In tal modo tutti i campi ereditati dalle superclassi sono pienamente inizializzati prima dellesecuzione degli initializer e del corpo del costruttore a livello delle sottoclassi.

Costruttori e polimorfismo
Lultimo aspetto legato al processo di inizializzazione distanza in Java il comportamento della JVM nellinvocazione dei metodi distanza dallinterno degli InstanceInitializationMethod. Questa situazione si verifica allorquando il programmatore decide di invocare uno o pi metodi distanza da un costruttore o da un initializer distanza. La particolarit di Java in tale situazione , paradossalmente, che non c alcuna particolarit. Linvocazione dei metodi distanza in tale contesto segue infatti le normali regole di binding dinamico del linguaggio. Questo costituisce una grossa differenza di comportamento rispetto ad altri linguaggi ad oggetti, primo fra tutti il C++, che pu comportare grossi problemi se non attentamente gestito. Analizziamo nei particolari il problema basandoci sul Listato 1. Nel momento in cui si costruisce unistanza della classe Derived, la JVM invoca il suo InstanceInitializationMethod che, a sua volta, come prima istruzione va ad invocare il metodo corrispondente della superclasse diretta. Nel metodo di inizializzazione distanza di Base (passi due e tre per quanto detto al paragrafo precedente) il compilatore avr inserito linvocazione dei due metodi distanza getX() ed instanceMethod(), utilizzati dal variable initializer della variabile x e dal costruttore. Bench entrambi i metodi siano dichiarati in Base, poich essi sono ridefiniti nella sottoclasse, saranno proprio le versioni di Derived ad essere invocate. Il tipo dinamico del reference d infatti proprio Derived. Questo comportamento causa due distinti problemi. In primo luogo la variabile x riceve il valore iniziale -1 anzich il valore 1, come quasi certamente era nelle intenzioni del programmatore. Potenzialmente ancora pi pericoloso il secondo problema: poich si sta invocando il metodo instanceMethod() ridefinito in Derived, proprio la copia della variabile i dichiarata nella sottoclasse, che nasconde la variabile i dichiarata
LISTATO 1
Metodi distanza ed initializer

fondamentale
conoscere il processo per evitare errori
A causa di questo comportamento si devono prendere alcune cautele nel disegno dei costruttori nelle sottoclassi, come si pu constatare dallesame del frammento di codice seguente:
class Base { public Base(int i) { }//codice non compilabile } class Derived extends Base{ }

Il compilatore rifiuta tale codice, segnalando che il costruttore Base() non presente. Infatti, in Derived il compilatore crea il costruttore di default ed il corrispondente InstanceInitializationMethod che, alla luce di quanto sopra discusso, come prima istruzione possieder linvocazione del metodo corrispondente di Base. A causa della presenza dellunico costruttore con un parametro di tipo int, in Base non esister tuttavia il costruttore di default e quindi nemmeno il metodo dinizializzazione distanza con lista dei parametri vuota. In definitiva, il metodo dinizializzazione distanza di Derived cercher di invocare un metodo inesistente. Concettualmente pi semplici sono i punti due e tre sopra introdotti. Al punto due la JVM raccoglie ed esegue tutti gli instance initialization block (si noti che non c limite al numero di tali blocchi, esattamente come avviene per gli static initialization block) e gli instance variable initializer presenti nella classe, mentre al punto tre esegue il corpo del costruttore corrispondente. Questo, tra laltro, risponde al quesito posto in precedenza: al momento in cui viene eseguito il corpo di un qualsiasi costruttore (punto 3), tutti gli initializer distanza sono gi stati invocati.

public class Base { private int x = getX(); public Base() { System.out.println(x = + x); instanceMethod(); } protected void instanceMethod() { System.out.println(In class Base); } protected int getX(){ return 1; } } class Derived extends Base{ private int i = 5; protected void instanceMethod() { System.out.println(In class Derived i = + i); } protected int getX(){ return -1; } public static void main (String a[]){ Derived d = new Derived(); } }

42

Computer Programming n. 143 - Febbraio 2005

PROGRAMMING
LISTATO 2
Esempio di inizializzazione di una gerarchia di classi e delle loro istanze

class Animale { static { 1. System.out.println(Classe Animale inizializzata); } { 2. System.out.println(Unistanza di Animale inizializzata); } public Animale(){ 3. System.out.println(Costruttore di Animale invocato); } } class Gatto extends Animale { static { 4. System.out.println(Classe Gatto inizializzata); } { 5. System.out.println(Unistanza di Gatto inizializzata); } public Gatto(){ 6. System.out.println(Costruttore di Gatto invocato); } } public class TestClass { static { 7. System.out.println(Classe TestClass inizializzata); } { 8. System.out.println(Unistanza di TestClass inizializzata); } public static void main(String[] args) { 9. new Gatto(); } }

in Base, ad essere utilizzata. Al momento dellesecuzione dellInstanceInitializationMethod di Base, tuttavia, gli initializer di Derived non sono ancora stati eseguiti, e quindi tale variabile si trova al valore di default. In definitiva si sta accedendo ad unistanza di Derived non pienamente inizializzata e quindi con uno stato iniziale diverso da quanto deciso dal programmatore. Questo comportamento del linguaggio comporta la necessit di prestare molta attenzione nellinvocare metodi distanza in fase di inizializzazione. La strategia conservativa quella di evitare in toto linvocazione di metodi distanza da initializer o costruttori, preferendo ad esempio i blocchi di inizializzazione distanza. Laddove questo non fosse possibile, lunica garanzia che nel futuro altri programmatori non vadano ad alterare la strategia di inizializzazione tramite ereditariet ed overriding, quella di invocare esclusivamente metodi privati, che sono risolti sempre staticamente, o addirittura final. Si noti che il problema assai insidioso, tanto che in C++ linvocazione di metodi virtuali dai costruttori trattata in modo peculiare, senza ricorrere al binding dinamico.

to al Listato 2, nel quale riportato lo scheletro di una semplice gerarchia di classi. La prima cosa che notiamo linizializzazione della classe MainClass (contenente il metodo main) e quindi linvocazione del suo ClassInitializationMethod (esecuzione della linea 7). Inizializzata tale classe, la JVM passa ad eseguire il metodo main. Lunica istruzione in esso presente comporta la costruzione di una nuova istanza di Gatto e questo un uso attivo di tale classe. Come conseguenza, lintera gerarchia Gatto-Animale verr a sua volta inizializzata (si noti come Object a questo punto sia gi stata inizializzata in quanto superclasse di MainClass). La JVM invocher quindi i ClassInitializationMethod di Animale e Gatto, in questordine esatto, eseguendo in definitiva il codice alle linee 1 e 4. Solo dopo aver terminato questa fase potr avvenire la costruzione dellistanza di Gatto richiesta, e questo ci riporta a quanto visto nei precedenti paragrafi. La JVM eseguir infatti gli InstancetInitializationMethod di Animale e Gatto che conterranno il codice degli initializer e dei costruttori dichiarati in tali classi. Per quanto detto, linvocazione dei metodi di inizializzazione avviene a partire dalle superclassi, quindi verr eseguito dapprima lInstanceInitializationMethod di Animale (linee 2 e 3) e successivamente quello di Gatto (linee 5 e 6). Si noti anche come la linea 8 non venga mai eseguita. La classe MainClass infatti inizializzata in seguito ad un suo uso attivo, ma non viene mai istanziata dallapplicazione. In conseguenza di ci, il suo InstanceInitializationMethod non viene invocato.

Conclusioni
Nei due articoli di questa breve serie abbiamo avuto modo di affrontare tutti gli aspetti del processo di inizializzazione in Java, con particolare enfasi sugli aspetti meno noti e pi intricati di tale attivit. Abbiamo visto come Java offra un grande supporto ai programmatori in questo ambito, ma anche come sia fondamentale conoscere perfettamente il processo per evitare linsorgere di errori. Allo stesso modo, e forse a maggior ragione, indispensabile la perfetta conoscenza del processo duale alla inizializzazione, vale a dire il rilascio della memoria detenuta dagli oggetti al momento della loro distruzione, per il quale rinviamo i lettori interessati alla bibliografia.

BIBLIOGRAFIA & RIFERIMENTI


[1] B. Venners Inside the Java virtual machine, II edition [2] B. Eckel Thinking in Java, III edition [3] B. Eckel Thinking in C++, II edition [4] The Java Language specification http://java.sun.com/docs/books/jls/html/index.hml [5] The Java Virtual Machine Specification http://java.sun.com/docs/books/vmspec/html/VMS pecTOC.doc.html

Mettiamo tutto insieme


Arrivati a questo punto, avendo visto in questo e nel precedente articolo della serie tutti gli aspetti dellinizializzazione in Java, possiamo finalmente ricapitolare lintero processo con un esempio. Facciamo riferimen-

Computer Programming n. 143 - Febbraio 2005

43