2015-06-13 18 views
5

Diese Frage kann dumm sein, aber ich will nur wissen, gibt es einen Unterschied?Welcher Weg zum Setzen von Feldern ist besser und warum?

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

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

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

Antwort

2

Weg 2 ist besser, weil es Ihnen eine einheitliche Möglichkeit gibt, einen Variablenwert festzulegen. Es birgt jedoch ein Risiko, da Sie eine ausschaltbare Methode in einem Konstruktor aufrufen. So ist die richtige Syntax mit dem Schlüsselwort final:

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

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

Mit final die Methode nicht außer Kraft gesetzt werden. Wenn Sie sich keine finale Methode leisten können, rufen Sie den Setter nicht in einem Konstruktor auf. Aber es ist normalerweise seltsam, einen Setter zu überschreiben.

Das ist gut, weil Sie später die Setter ändern möchten:

  • Add Argument überprüft und eine IllegalArgumentException werfen, wenn erforderlich.
  • hinzufügen Zähler
  • Beobachter Notify (in einer beobachtbaren Muster)
  • es einen synchronisierten Block Make
  • Thread-Sicherheit zur Verfügung zu stellen
  • ...

Und Sie werden es tun müssen, um in ein einzelner Ort. Dies ist eine Implementierung von 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 

Sie sich nicht um die Optimierung und Kosten der zusätzlichen Methodenaufruf kümmern. JVM kann diesen Code normalerweise durch Inlining-Methoden optimieren.

Was wirklich die Entwicklung verlangsamt, ist die Suche nach einem Fehler. Diese Methode hilft Ihnen, weniger Fehler zu machen und Ihren Code leichter zu pflegen.

+0

Aber ist nicht Aufruf eine Methode macht es langsamer? – Aero

+0

Verstanden. Vielen Dank. – Aero

+2

Möglicherweise besteht ein Sicherheitsrisiko beim Aufruf einer öffentlichen überschreibbaren Methode in Ihrem Konstruktor – dkatzel

0

Nun, für mich ist der Weg mehr Java. Was ich meine, ist, dass wir wissen sollten, was Konstruktor tun soll (um Instanzeneigenschaften zur Initialisierungszeit einzurichten) und was tun sollte (stellen Sie einen öffentlichen offenen Punkt zur Verfügung, um die Eigenschaften der Instanz zu dem von Ihnen gewünschten Zeitpunkt zu ändern).

wir meinen opition

einfach jede Logik in den Konstruktor nicht platzieren sollte.

4

Ich vermute, es gibt keine "bessere" Art und Weise, wollen nur zu Ihrem Zweck zu der Zeit.

Ich bevorzuge Way # 1 die meiste Zeit. Dies ist, weil ich versuche, Code als Encapsulated wie möglich zu machen. Es kann auch auf eine Art und Weise als Functional Art der Programmierung von Java betrachtet werden, da Sie Nebenwirkungen reduzieren. Manchmal eliminieren sie alle zusammen.

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

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

Kann als ...

es, wenn Sie den Wert Feld nach der Instanzierung ändern müssen nicht
class A{ 
// common code 
private final int field; 

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

Ja, neu geschrieben werden, arbeiten. Auch kann Feld ein anderes Objekt oder eine Sammlung sein.

Aber bei den Bemühungen der Klasse als unveränderlich wie möglich zu machen, werden die Felder, die als Privat letzte markiert werden können, sind so gemacht.

Und natürlich können Sie das nicht mit einer Setter-Methode tun.

+0

upvote für die ultimative Kapselung –

Verwandte Themen