2012-09-24 12 views
7

Leute,Java - Klonen Sie die Eigenschaft innerhalb Getter-Methode

ich durch Java beste Codierpraktiken hier erwähnt gehen
http://viralpatel.net/blogs/most-useful-java-best-practice-quotes-java-developers/

2. Zitat sagt,

Zitat 2: Niemals eine machen Instanz Felder der Klasse Öffentlichkeit

Ich stimme zu, das ist absolut richtig, aber ich blieb stecken, weil ich der Empfehlung des Schriftstellers nur wenige Zeilen unter diesem Zitat folgte.

Er sagt:


private String[] weekdays = 
    {"Sun", "Mon", "Tue", "Thu", "Fri", "Sat", "Sun"}; 

public String[] getWeekdays() { 
    return weekdays; 
} 

Aber das Schreiben Getter-Methode nicht genau unser Problem lösen. Das Array ist weiterhin zugänglich. Der beste Weg, um es unmodifizierbar zu machen, besteht darin, einen Klon des Arrays anstelle des Arrays selbst zurückzugeben. Somit wird die Getter-Methode zu

geändert wird
public String[] getWeekdays() { 
    return weekdays.clone(); 
} 

Ich habe ich nie clone() in jeder Getter-Methode von Java-Klasse verwendet.

Ich frage mich (wie es erwähnt wird, eine der guten Praktiken sein) -, warum innerhalb Getter-Methode ein should use/shouldn't useclone()? und in welchen Szenarien?

Ist es eine gute Programmierpraxis für Java?

Dank

+2

IMO - Für unveränderliche Objekte und primitive Datentypen ist kein Klonen erforderlich. Für alles andere, wenn wir wirklich wollen, dass unsere Daten sicher sind, müssen wir die Kopie und nicht das Original zurückgeben. –

+2

Sie könnten 'Arrays.asList (Wochentage)' zurückgeben, die unveränderlich sind. – Jivings

+2

@Jakings nicht wahr. Die Liste akzeptiert keine neuen Elemente, aber die Methode set() funktioniert. –

Antwort

3
private String[] weekdays =  
    {"Sun", "Mon", "Tue", "Thu", "Fri", "Sat", "Sun"}; 

public String[] getWeekdays() 
{  
    return weekdays; 
} 

Wenn Sie eine Menge von unethisch Dinge nicht clone Methode verwenden, kann der Benutzer dieser Klasse tun:

  1. Änderung der Reihenfolge der Tage,
  2. ändern der Name der Tage,
  3. ...

Die Rückgabe eines Klons hat jedoch keinen Einfluss auf die Klasse und die Daten. Daher sind andere Benutzer der Klasse nicht betroffen.

+0

Aber ich habe diese klon() Methode Empfehlung auf keiner Website zuvor gesehen. Ich habe nicht gesehen, dass die meisten Programmierer (sogar einige Java-Geeks) das in ihren Beispielen verwenden. Ich bezweifle, dass das eine gute Programmierpraxis ist? : O –

+0

@bomslang Eine Menge wird Ihre Anforderungen fallen. Wie Azodious darauf hingewiesen hat, kann das Nicht-Klonen (was eine andere Kopie der Daten beweist) zu unerwarteten Problemen für Ihre Klasse führen, aber Sie müssen entscheiden, ob dies das gewünschte Verhalten ist. Der Grund, warum Sie es wahrscheinlich nicht sehen, ist, weil es für die meisten Leute mehr tippen. Wenn Sie in der Swing-API nachsehen, sehen Sie eine Menge ähnlicher Praktiken. Wenn Sie 'Dimension' zurückgeben, erstellt die Klasse oft ein neues' Dimension'-Objekt, wobei sie ihre interne Referenz als Kern dieser neuen Klasse verwendet. Klonen es. – MadProgrammer

+2

Ja, ist es. und persönlich habe ich es in einem Fall verwendet, der deinem Beispiel fast ähnlich ist. Aber es sollte nicht blind verwendet werden, denn wenn ein schweres Objekt geklont wird, führt dies zu Speicherproblemen. Klonen Sie also nur die Daten, die ein Benutzer nicht ändern sollte. – Azodious

2

Sie clone() or System.arraycopy() auf get(), wenn Sie garantieren möchten, dass das gesamte Objektdiagramm (das das Array enthält) unveränderlich ist. Dies geschieht normalerweise, wenn die API, die das Array freigibt, public ist und Einschränkungen für die Werte im Array bestehen oder wenn auf die Objekte von mehreren Threads zugegriffen wird. In solchen Fällen ist die Unveränderlichkeit wichtig.

Nehmen wir an, Sie haben ein GroceryStore Objekt, das getItemsSortedByPrice() Methode hat. Sie behalten die Elemente in einem Array, das die Reihenfolge nach Preis verwaltet, aber wenn Sie dieses Array zurückgeben, kann der Client-Code möglicherweise das Array ändern und die (internen) Invarianten Ihres Objekts aufbrechen.

Wenn dies interner Code (d. H.) Nicht Teil der öffentlichen API ist, und Sie wissen, dass Sie das Array nicht ändern, dann ist Klonen/Coping wahrscheinlich nicht notwendig, da es Leistung ohne wirklichen Nutzen verletzt.

Alles hängt vom Kontext ab.

Arrays sind nur Objekte und alle (Un) Veränderbarkeitsregeln/-praktiken, die für ein gewöhnliches Objekt gelten, gelten auch für Arrays.

+1

+1 für System.arrayCopy (), obwohl ich die besser verwendbare Version Arrays.copyOf() empfehlen würde (die intern natürlich System.arrayCopy() verwendet) –

1

Ich denke, Ihr Anwendungsfall stimmt nicht mit dem vorgeschlagenen Java-Code überein. Das Beispiel ist für einen anderen Anwendungsfall als Ihres.

Ein abschließendes Array klingt für mich wie Enums und ich denke, das entspricht Ihrer Anforderung viel besser.

5

Dies wird in dem Buch "Effektive Java" von Joshua Bloch diskutiert. Es gibt einen Abschnitt mit dem Namen "Erstellen Sie defensive Kopien bei Bedarf" (Abschnitt 39 in der 2. Auflage).

Ich glaube, Google Bücher können Sie eine Vorschau des Abschnitts sehen lassen.

Ein gutes Buch zu Themen wie diesem zu verweilen.