Perchè più chiamate verso le stesse classi "Il costruttore dall'interno di un costruttore non funzionerebbe?

5

Dai un'occhiata al seguente frammento:

public class Foo {
int digit;
String name;

Foo (int d, String n) {
    this(d);
    // cannot do following.
    //compile-time error: Constructor call must be first statement in a Constructor 
    //this(n);
}

Foo (int p) {
    digit = p;
}

Foo (String q) {
    name = q;
}

Quale sarebbe la ragione di questa restrizione? Capisco perché chiamare Costruttore (sia in un Costruttore o in un metodo) deve essere la prima affermazione - l'oggetto dovrebbe essere inizializzato correttamente prima di essere usato. Quello che non ottengo è che il compilatore non permette di chiamare più costruttori della stessa classe all'interno di un costruttore. Non vedo alcun problema con questo costrutto, sia per quanto riguarda l'inizializzazione che gli invarianti.

Sarebbe bello se qualcuno potesse far luce su ciò che mi manca qui ...

Grazie!

    
posta Chaitanya 23.02.2012 - 08:44
fonte

2 risposte

8

I costruttori non sono solo "metodi che vengono chiamati quando viene creato l'oggetto", sono concettualmente diversi.

Lo scopo del Costruttore è di limitare ciò che gli stati possono essere inizialmente gli oggetti. Un oggetto appena creato viene azzerato su tutti i campi (null / 0 / falso) e potrebbe essere uno stato non valido nel tuo programma. Ad esempio, un oggetto Cliente nell'applicazione deve essere limitato per avere sempre un ID cliente > 0 - quindi definisci un costruttore che prende quell'id e lo controlla.

In questa luce non è necessario chiamare due costruttori: dopo aver chiamato il primo, l'oggetto è già in uno stato coerente. Il secondo costruttore riceverà un oggetto inizializzato che è una violazione del suo scopo (facendo 0 = > inizializzato).

Quello che vuoi fare in questo caso è introdurre metodi privati che faranno parte di quell'inizializzazione e chiamarli o fare in modo che costruttori più specifici chiamino quello più generale (che è un modello molto comune):

Foo (int d, String n) {
    digit = d;
    name = n;
}

Foo (int p) {
    this(p, null)
}

Foo (String q) {
    this(0, q)
}
    
risposta data 23.02.2012 - 09:35
fonte
4

Il motivo è che la specifica del linguaggio Java lo dice. Probabilmente è stato scritto per consentire ciò che descrivi, ma non gratuitamente: far rispettare l'ordine rende le cose più semplici. Pensa all'eredità e alle chiamate a super() . Se non fosse la prima dichiarazione in un costruttore, la sottoclasse potrebbe fare qualcosa con una superclasse che non è ancora stata costruita. A che punto sarebbe this se l'onnipresente superclasse Object non fosse ancora stata costruita?

Consentire un ordine arbitrario di costruttori non sarebbe stato molto utile, ma avrebbe complicato le specifiche del linguaggio e il compilatore (molto, immagino).

    
risposta data 23.02.2012 - 09:38
fonte

Leggi altre domande sui tag