1. E' allocato spazio per Under
e tutte le sue superclassi,
quindi in particolare è allocato spazio per il campo what
di
Under
e per il campo what
di
Super;
2. Tutti i campi di Under
e tutti quelli delle sue superclassi
sono inizializzati al loro valore default, quindi in particolare what
di
Under
e
what
di
Super
sono entrambi inizializzati
a zero;
3. E' automaticamente invocato il costruttore
di Super
come prima istruzione del costruttore
di Under.
Infatti il costruttore di Under
{
printThis(); }
equivale a:
{
super(); printThis(); }
4. Sono eseguiti gli inizializzatori dei
campi di Super,
quindi what
di
Super
è inizializzato a 1;
5. E' invocato il costruttore di Super
che, dopo aver automaticamente
invocato il costruttore di Object,
invoca lo statement
printThis();
6. Il metodo printThis
presente in Super
è presente anche in Under
con la stessa signature (printThis
è overrided in Under)
e poiché qui stiamo effettivamente costruendo un oggetto Under
(stiamo infatti vedendo cosa
succede quando si invoca new
Under()) viene allora invocato
il metodo printThis
di
Under;
7. Il metodo printThis
di
Under
stampa il valore what
di
Under
che a questo punto vale ancora
zero (perché è stato inizializzato a zero al punto 2 e non
è stato ancora eseguita la sua inizializzazione a 3). Quindi viene
stampato zero!
8. Terminato il costruttore di Super
(cominciata al punto 3) sono
eseguite le inizializzazioni dei campi di
Under,
quindi what
di
Under
viene inizializzato a 3 solo
adesso!
9. Prosegue il costruttore di Under
con la chiamata printThis
che stampa il valore what
di
Under
che a questo punto vale 3.
La
prima ovvia banale risposta potrebbe essere: nulla, stampa sempre 103!
No,
le cose non stanno così. Lo abbiamo già visto nella soluzione
del quiz 5 del settembre dello scorso anno. Anche se allora avevo promesso
di non parlare più dell'uso del modificatore final
in Java,
eccomi qui di nuovo!
La
cosa è molto sottile e molto importante e di solito si tende a dimenticarsi
di cosa voglia dire usare final.
Si pensa a final
solo per
dichiarare delle costanti, ma ci si dimentica quando queste costanti
siano inizializzate.
Ebbene
in questo caso i campi final
inizializzati
con espressioni valutabili a tempo di compilazione (come ad esempio le
semplici espressioni 1 o 3) sono inizializzati subito dopo il precedente
passo 2 e quindi in un passo 2.bis cosi congegnato:
2.bis
Tutti
i campi di Under
e tutte
le sue superclassi che hanno il modificatore final
con espressioni
valutabili a tempo di compilazione sono inizializzati a questi valori e
quindi, nel caso particolare, what
di Super
è
inizializzato a 1 e what
di Under
è
inizializzato a 3.
In
questo modo il successivo passo 7 (chiamata di printThis
in Under)
trova what
di Under
che vale
3, e quindi il nostro programmino stampa quindi 133.
Tutto chiaro!
Spero
che tutto sia stato abbastanza chiaro. Potete in ogni caso contattarmi
via email per ulteriori chiarimenti
e disquisizioni.