L'unica vera differenza è nell'ordine delle operazioni. I campi inizializzati nella loro dichiarazione vengono valutati prima che venga chiamato il costruttore della classe. I campi inizializzati in una sottoclasse in questo modo verranno valutati dopo il completamento del costruttore del super, ma prima che venga chiamato il costruttore della sottoclasse.
consideri il seguente esempio:
ho una classe di test:
public class Tester {
Tester (String msg) {
System.out.println(this + ":" + msg);
}
}
ho una classe di super:
public class Test {
protected Tester t1 = new Tester("super init block");
Test (String constructorMsg) {
new Tester(constructorMsg);
}
}
e ho una sottoclasse:
Public class TestSub extends Test {
private Tester t2 = new Tester("sub init block");
TestSub(String constructorMsg) {
super(constructorMsg);
new TTester("sub constructor");
}
}
Nel mio main
metodo, creo un'istanza di TestSub
:
public static void main(String[] args) {
new TestSub("super constructor");
}
i risultati sono i seguenti: modifiche
[email protected]:super init block
[email protected]:super constructor
[email protected]:sub init block
[email protected]:sub constructor
Jon Skeet colpiscono di nuovo –
Non si ottiene anche lo stesso bytecode con un'istanza di inizializzazione? Direi che la risposta è sì. –
@mmyers: Sì, esattamente lo stesso di nuovo. –