Unverwundbarkeit in Java

8

Ich versuche, etwas in die Definition von "Unveränderlichkeit" zu integrieren.

Punkt (3) hier sagt, als eine der Regeln zum Erstellen unveränderliche Objekte,

  

Erlaube den Unterklassen nicht, Methoden zu überschreiben. Der einfachste Weg, dies zu tun   ist die Klasse als endgültig zu deklarieren. ...

Überschriebene Methoden werden in Instanzen von Unterklassen ausgeführt. Und von dem, was ich weiß, ist eine unveränderliche Klasse eine, von der die Objekte in den Speicher "geschnitzt" werden, sobald sie instanziiert sind-- Keines seiner Mitglieder und somit das Objekt kann nicht verändert werden.

Setzt man diese zusammen - gilt die Definition von "unveränderlich" sowohl für Klassen als auch für die Objekte? Indem ich die Methoden abschließe, verhindere ich, dass ihre Methoden überschrieben werden, wenn die Klasse erweitert wird. Ich sehe nicht, wie die Methoden einer unveränderlichen Klasse weiter vervollständigt werden, um ihre Objekte unveränderlich zu machen.

    
Roam 21.11.2013, 22:07
quelle

7 Antworten

7

Wenn Sie Ihre Klasse als unveränderlich dokumentieren, können Benutzer dieser Klasse sicher davon ausgehen, dass jede Instanz dieser Klasse unveränderlich ist.

Das Problem besteht darin, dass es nichts verbietet, wenn eine Unterklasse Ihrer Klasse unterklassifiziert wird, einer untergeordneten Klasse änderbare Zustände und Methoden hinzuzufügen oder sogar Methoden zu überschreiben und sie dazu zu bringen, diesen neuen Status zu mutieren. Die Annahme der Benutzer der Klasse fällt also auseinander. Den Abschluss der Klasse zu machen, macht das unmöglich.

    
JB Nizet 21.11.2013 22:15
quelle
1
  

Ich sehe nicht, wie die Finalisierung der Methoden einer unveränderlichen Klasse ihre Objekte unveränderlich macht.

Wenn eine Klasse final ist, ist ihre Methode final redundant; Da nichts von der Klasse abgeleitet werden kann, kann nichts die Methoden außer Kraft setzen, unabhängig davon, ob sie als final deklariert sind oder nicht. Vorausgesetzt, die Klasse, die Sie definiert haben, ist unveränderlich, wenn es final ist, kann es keine Unterklassen geben, die nicht unveränderbar sind (weil es überhaupt keine Unterklassen geben kann).

    
T.J. Crowder 21.11.2013 22:14
quelle
1

Ich nehme an, wenn die Objekte einer Klasse unveränderlich sind, dann können Sie sagen, dass die Klasse auch unveränderlich ist. String -Objekte sind unveränderlich, daher könnte man sagen, dass die String -Klasse unveränderlich ist.

Wenn Sie Ihre Methoden final erstellen, verhindern Sie, dass eine unbekannte Unterklasse Folgendes tut:

%Vor%

Es verhindert, dass eine Unterklasse Vererbung und Polymorphie verwendet, um die Daten in Ihrer Klasse zu mutieren (ändern). Es verhindert auch, dass eine Unterklasse einen eigenen Zustand einführt, der veränderbar sein könnte.

Unveränderlichkeit ist nicht etwas, das man einfach erklären kann; Sie müssen es mit mehreren Techniken erzwingen, die in die Java-Sprache integriert sind. Machen Sie Ihre Methoden final ist einer von ihnen.

    
rgettman 21.11.2013 22:14
quelle
1
  

gilt die Definition von "unveränderlich" sowohl für Klassen als auch für die   Objekte?

Sehen Sie, wie ein class der Bauplan eines Objekts ist, ja?

Der wichtigere Unterschied, der hier gemacht werden muss, ist folgender: - Wenn Sie final überall hinzufügen, wird Ihre Klasse / Ihr Objekt NICHT unveränderlich gemacht. überhaupt.

Bedenken Sie Folgendes:

%Vor%     
yamafontes 21.11.2013 22:16
quelle
1

Unveränderlich bedeutet, dass sich das Objekt NICHT ändern kann. Das Standard-String-Objekt in Java ist also unveränderlich - Sie können es übergeben, Sie können beliebig viele Referenzen speichern, aber Sie können es nicht ändern. Wenn Sie eine Zeichenfolge ändern möchten, verwenden Sie einen StringBuilder (oder StringBuffer), um sie anzufügen oder zu ändern.

Aber String ist eine vom System bereitgestellte Klasse, so dass ihre Unveränderbarkeit als bare Münze angenommen werden kann. Wenn Sie eine unveränderbare Klasse erstellen möchten, können Sie dies nur tun, indem Sie nur Methoden bereitstellen, die garantiert den internen Status nicht ändern. Da eine Klasse normalerweise überschrieben werden kann, ist es denkbar, dass ein Codeabschnitt die Klasse unterklassifiziert, nur um den internen Status zu ändern.

Daher:

  1. Machen Sie alle Ihre Felder intern privat. Sie sollten auch als final markiert werden, da sie nur vom Konstruktor gesetzt werden sollten.
  2. KEINE Felder zurückgeben, die selbst Objekte sind, außer sie sind auch unveränderlich.
  3. Markieren Sie das Objekt final und alle Methoden final
  4. Stellen Sie KEINE Methoden zur Verfügung, die den internen Status ändern können
  5. Operationen wie clone (), add (), subtract (), split (), diff (), combine () usw., die neue Objekte ausspeien, sollten nicht auf das vorhandene Objekt oder seine Felder verweisen, um auf der sicheren Seite zu sein . Verwenden Sie Deep Copy, um sicherzustellen, dass sie threadsicher sind.
  6. Wenn Ihr Objekt Sammlungen anderer Objekte zurückgibt, verwenden Sie Methoden wie Collections.unmodiableList (), unmodiableMap () usw., um Personen daran zu hindern, diese Sammlungen zu missbrauchen.
  7. Wenn das Objekt oder ein beliebiges Feld Interfaces implementiert, die für Lese- / Schreiboperationen ausgelegt sind, dann werden Exceptions in der Implementierung jeder Schreiboperation ausgelöst.

Unveränderlichkeit ist eine gute Eigenschaft für Objekte (insbesondere solche, bei denen das Eigentum ein Problem sein kann oder Nebenläufigkeit ist), aber der Nachteil ist, dass Sie viele Wegwerfobjekte konstruieren können und daher ineffizient sein können. Es ist also ein Kompromiss und es hängt davon ab, was Sie für die Objekte benötigen, ob es sich lohnt.

    
locka 21.11.2013 22:36
quelle
1

Es gibt wesentliche Unterschiede in der Appliance des Schlüsselworts final .

Gerät ...

  • ... bis classes verbietet Sub-Classing (und damit auch Methoden-Overrides)

  • ... zu Methoden verbietet Methodenüberschreibungen
  • ... bis Instanzvariablen sichert die Unveränderlichkeit dieser Felder und damit auch für ganze Objekte , falls für alle angegeben, da finale Variablen nur einmal geschrieben werden können Konstruktion.

Dokumente:

Sam 21.11.2013 22:13
quelle
0

Objekte definieren Verhalten und Zustand. Unveränderlichkeit bezieht sich auf ein Objekt, das nach seiner Erstellung seinen internen Zustand nicht ändert.

das macht es einfacher mit Threads zu arbeiten, neben anderen Vorteilen, hier ist ein Beispiel aus der Guave einer unveränderlichen Liste. Ich kann seit dem im neuen Jahr keine Links mehr posten ... Ссылка .com /svn/trunk/javadoc/com/google/common/collect/ImmutableList.html

Um Ihre Frage zu beantworten, begrenzt das Finalisieren von Methoden die Vererbung, aber nicht die Unveränderbarkeit.

    
Hernan Arroyo 21.11.2013 22:14
quelle

Tags und Links