2015-06-13 5 views

risposta

2

Way 2 è migliore perché offre un modo unificato per impostare un valore variabile. Ma comporta un rischio, perché stai chiamando un metodo sovrascrivibile in un costruttore. Così la sintassi destra sta usando la parola finale:

public final void setField(int field){ 
    this.field = field; 
} 

//way 2 
public A(int field){ 
    setField(field); 
} 

Con final non sarà sovrascritto il metodo. Se non puoi permetterti di avere un metodo finale, non chiamare il setter in un costruttore. Ma di solito è strano scavalcare un setter.

Questo è un bene perché si può decidere di cambiare il setter in seguito:

  • controlli Add argomento e gettare un IllegalArgumentException quando richiesto.
  • Aggiungere un contatore
  • Segnalatemi osservatori (in un modello osservabile)
  • Ne fanno un blocco sincronizzato per fornire thread-sicurezza
  • ...

E si dovrà farlo in un posto unico Si tratta di un'implementazione di DRY principle.

public final synchronized void setField(int field){ 
    if (0 <= field && field <= MAX_VALUE) { 
     this.field = field; 
    } else { 
     throw new IllegalArgumentException(); 
    } 
} 

//still has all the benefits of setter 
public A(int field){ 
    setField(field); 
} 

A = new A(-1) //throws IllegalArgumentException 

Non preoccuparti per l'ottimizzazione e le spese di chiamata di metodo supplementare. In genere, JVM può ottimizzare tale codice integrando i metodi.

Ciò che rende lo sviluppo più lento è la ricerca di un bug. Questo metodo ti aiuta a fare meno errori e a mantenere più facilmente il tuo codice.

+0

Ma l'invocazione non è un metodo che lo rende più lento? – Aero

+0

Capito. Grazie. – Aero

+2

Potrebbe esserci un rischio per la sicurezza di chiamare un metodo di sovrascrittura pubblico all'interno del costruttore – dkatzel

0

Bene, per me, il modo in cui si è Più Java. Ciò che intendo è che dovremmo sapere cosa dovrebbe fare il costruttore (per impostare le proprietà delle istanze al momento dell'inizializzazione) e cosa dovrebbe fare il setter (fornire un punto pubblico aperto per modificare le proprietà dell'istanza nel momento desiderato).

non dovremmo mettere qualsiasi logica nel costruttore

solo la mia opition.

4

Sospetto che non ci sia un modo "migliore", voglio solo essere adatto al tuo scopo in quel momento.

Preferisco la modalità numero 1 per la maggior parte del tempo. Questo perché cerco di creare codice come Encapsulated il più possibile. Può anche essere considerato un modo di programmazione Java Functional, dal momento che si stanno riducendo gli effetti collaterali. A volte eliminandoli tutti insieme.

class A{ 
// common code 
private int field; 
public void setField(int field){ 
    this.field = field; 
} 

//way 1 
public A(int field){ 
    this.field = field; 
} 
} 

può essere riscritta come ...

class A{ 
// common code 
private final int field; 

//way 1 
public A(int field){ 
    this.field = field; 
} 

Sì, non funziona se è necessario modificare il valore del campo dopo l'istanza. Potrebbe anche essere campo un altro oggetto o raccolta.

Ma nello sforzo di rendere la classe come immutabile possibile, i campi che possono essere contrassegnati come finale privato sono fatto così.

E ovviamente non è possibile farlo con un metodo setter.

+0

upvote per l'incapsulamento finale –

Problemi correlati