2016-04-07 18 views
5

Capisco che il concatenamento del costruttore passi dal più piccolo costruttore al più grande. Per esempioConcatenamento del costruttore senza questo()

public MyChaining(){ 
     System.out.println("In default constructor..."); 
    } 
    public MyChaining(int i){ 
     this(); 
     System.out.println("In single parameter constructor..."); 
    } 
    public MyChaining(int i,int j){ 
     this(j); 
     System.out.println("In double parameter constructor..."); 
    } 

Inoltre mi pare di capire che la chiamata a this() e super() deve essere in prima linea. Ma è possibile (e se sì, è efficiente) bypassare quei costruttori di limite e di catena diversi?

Ad esempio, ho due costruttori che condividono del codice.

public Location(String _Name) throws IOException, JSONException { 
     //Three lines of unique code (must be executed before the shared code) 
     //Shared code 
    } 

    public Location(JSONObject json) { 
     //Shared code 
    } 

È in alcun modo possibile che il primo costruttore chiami il secondo?

+0

@Philipp sì è e sarà fatto così. Mi stavo chiedendo se si può fare attraverso il concatenamento perché non sono riuscito a trovare una risposta altrove – Akaitenshi

risposta

4

Sicuro. Se si dispone di una funzione

JSONObject foo(String)

allora static è possibile scrivere

public Location(String _Name) throws IOException, JSONException { 
    this(foo(_Name)); 
} 
3

L'unico modo per eseguire il codice condiviso senza chiamare this è che entrambi i costruttori chiamino un metodo di inizializzazione che conterrebbe il codice condiviso.

+0

Sì, lo so che si può fare in questo modo. Mi stavo chiedendo se si può fare attraverso il concatenamento e solo – Akaitenshi

+1

Il metodo init() ha un'altra difficoltà. Non è possibile inizializzare i campi dell'istanza finale in quel metodo. –

+0

@Akaitenshi Il concatenamento è fatto solo con 'this();' e deve essere la prima riga del costruttore. – Eran

1

Una risposta in qualche modo diversa: non farlo.

I costruttori sono come tutti gli altri membri della classe: dovrebbero avere un senso "del tutto". Avere costruttori che offrono interfacce completamente "diverse" o "indipendenti" per l'utente mi sembra un odore di codice.

Vedi; se puoi "disegnare" una linea attraverso la tua classe; e scopri che alcuni elementi vanno sempre sul lato sinistro, e molti altri vanno sul lato destro di quella linea; quindi questa è un'indicazione che forse dovresti dividere la tua classe lungo quella "linea" e creare invece due classi.

Se si desidera veramente creare lo stesso tipo di oggetto da contesti diversi; quindi prova ad identificare il "comune denominatore pezzo X"; e fornire un costruttore esattamente per quella X. E quindi usare metodi di fabbrica che magari usano quel costruttore comune in modi diversi. Questo significa che si sia fornire metodi statici all'interno della stessa classe, come

static Location generateLocationFromFoo(Foo foo) { ... } 
static Location generateLocationFromBar(Bar bar) { ... } 

o di andare un passo oltre e creare una classe factory separato che viene utilizzato per generare gli oggetti reali Posizione per voi.

+0

Mi dispiace ma non capisco fino in fondo la tua ultima frase. Vuoi dire che posso chiamare un costruttore da un metodo all'interno della stessa classe e usare questo metodo per istanziare il mio oggetto? – Akaitenshi

+0

Aggiornamento della risposta; Spero possa aiutare. – GhostCat

+0

Quindi dovrei chiamare il costruttore all'interno di 'generateLocation' e chiamare' objName.generateLocation() 'sul mio main o quando voglio l'oggetto? – Akaitenshi

1

trovo il concatenamento dal più piccolo costruttore per il più grande modello del tutto illeggibile, in quanto la logica di costruzione attuale si sviluppa su molti metodi diversi.

trovo più leggibile per:

  • Avere un costruttore "principale" che gestisce completamente l'inizializzazione esempio
  • avere tutti gli altri costruttori chiamano

Anche io un po 'piace molto concatenando (difficile ottenere il codice effettivo se si esegue il drill down da un semplice costruttore), quindi tendo a scrivere tutti gli altri costruttori per chiamare direttamente quello "principale" a meno che non si tratti di codice duplicato.

È sempre possibile aggirare la limitazione "this() deve essere la prima istruzione" chiamando un metodo statico, a meno che non si tenti di fare qualcosa che questa regola sta effettivamente cercando di impedire (ad esempio, utilizzare un oggetto semiinizializzato). Si noti che la funzione chiamata deve essere statica esattamente per impedire all'utente di utilizzare l'oggetto semiinizializzato.

Problemi correlati