Warum private statische finale Listen / Sets / Maps nicht modifizierbar machen?

8

Ich habe gerade einen Code gelesen, der von einem erfahrenen Programmierer geschrieben wurde, und ich stieß auf Folgendes:

%Vor%

Wie Sie sehen, ist dies eine Klasse, die zur Formatierung der Protokollausgabe verwendet wird. Was mir jedoch aufgefallen ist, war der Code im statischen Initialisierungsblock: PREFIXES = Collections.unmodifiableMap(prefixes); .

Warum wurde PREFIXES zu einer nicht änderbaren Karte gemacht? Es handelt sich um eine private Konstante, daher besteht kein Risiko, dass die Daten außerhalb dieser Klasse geändert werden. Wurde die Unveränderlichkeit der Konstante mit einem Gefühl der Vollständigkeit versehen?

Persönlich hätte ich direkt PREFIXES als HashMap und dann put die Schlüssel / Wert-Paare direkt initialisiert, ohne eine Dummy-, Platzhalter-Map zu erstellen oder das Feld zu einer unveränderlichen Map zu machen. Fehle ich hier etwas?

    
Konstantin 10.12.2012, 01:23
quelle

6 Antworten

9

Indem er die Liste unmodifizierbar machte, dokumentierte der Autor seine Annahme, dass sich die Werte niemals ändern werden. Wer später diese Klasse bearbeiten wird, kann diese Annahme nicht nur sehen, sondern wird auch daran erinnert, falls sie jemals unterbrochen wird.

Dies ist nur sinnvoll, wenn Sie die Langzeitansicht verwenden. Es reduziert das Risiko neuer Probleme durch Wartung. Ich mache diese Art zu programmieren gerne, weil ich dazu neige, auch in meinen eigenen Klassen Dinge zu zerbrechen. Eines Tages könnten Sie sich für eine schnelle Lösung entscheiden und Sie vergessen eine Annahme, die ursprünglich gemacht wurde und für die Korrektheit relevant ist. Je mehr Sie den Code sperren können, desto besser.

    
Peter Becker 10.12.2012, 03:02
quelle
9

Wenn Sie versehentlich return PREFIXES von einer Methode entfernen, kann plötzlich jeder andere Code das ändern. Konstanten unveränderlich zu machen, schützt gegen deine eigene Dummheit, wenn du diesen Code in der Zukunft um 3 Uhr morgens änderst.

    
Louis Wasserman 10.12.2012 02:55
quelle
3

Es ist überraschend einfach, eine private Map, Collection oder Array zu haben, die von außerhalb der Klasse geändert werden kann. Du würdest es als final markieren, warum würde nicht auch angegeben, dass es auch unveränderlich sein soll?

    
Tom Hawtin - tackline 10.12.2012 01:27
quelle
3

Angenommen, dein Freund verlässt seinen Job und ein weniger erfahrener Programmierer übernimmt das Kommando. Der weniger erfahrene Programmierer versucht, den Inhalt von PREFIXES irgendwo in einer anderen Methode innerhalb derselben Klasse zu modifizieren. Es ist unveränderbar, es wird nicht funktionieren. Es ist der richtige Weg zu sagen: "Das ist eine Konstante, ändere sie niemals."

    
Diego Basch 10.12.2012 01:36
quelle
1

Die Map-Schnittstelle kommuniziert nicht, dass etwas unveränderlich oder nicht änderbar sein soll.

Die folgenden Ansätze funktionieren in Eclipse-Sammlungen (früher GS-Sammlungen).

%Vor%

Dadurch wird eine Map erstellt, die vertraglich unveränderbar ist, da ImmutableMap keine mutierenden Methoden in seiner API hat.

Wenn Sie die Map-Oberfläche beibehalten möchten, funktioniert diese Vorgehensweise ebenfalls.

%Vor%

Sie sollten feststellen, dass in beiden Fällen kein statischer Block erforderlich ist.

Hinweis: Ich bin ein Committer für Eclipse Collections.

    
Donald Raab 10.12.2012 17:57
quelle
0

Wenn eine Sammlung endgültig ist, können Sie ihr kein neues Objekt hinzufügen. Es ist jedoch immer noch möglich, Objekte zu demselben Objekt hinzuzufügen oder zu entfernen.

Wenn Sie es nicht ändern können, können Sie der Sammlung nicht einmal Elemente hinzufügen oder entfernen. Daher ist es immer ratsam, die Sammlung nicht modifizierbar zu machen, anstatt sie nur als endgültig zu speichern.

    
Johnson Carneiro 28.07.2017 05:14
quelle