Befolgt die Implementierung des String-Speicherpools von Java das Flightweight-Muster?
Warum ich diesen Zweifel habe, sehe ich, dass in Intern kein extrinsischer Staat involviert ist. In GoF habe ich gelesen, dass es ein Gleichgewicht zwischen intrinsischem und extrinsischem Zustand geben sollte. Aber im Praktikum ist alles intrinsisch.
Oder sollen wir sagen, dass es keine strenge Regel in Bezug auf Attribute gibt und es einfach ausreicht, Objekte zu teilen, um Speicher zu reduzieren, um es als ein Fliegengewicht zu bezeichnen.
Bitte helfen Sie mir zu verstehen.
Ja, die String.intern()
-Implementierung folgt dem Fliegengewichtsmuster.
Wie das javadoc sagt
Gibt eine kanonische Darstellung für das String-Objekt zurück. Ein Pool von Strings, anfangs leer, werden privat von der Klasse String verwaltet.
Wenn die interne Methode aufgerufen wird, wenn der Pool bereits a enthält Zeichenfolge, die diesem String-Objekt entspricht, wie vom Gleichheitszeichen (Object) bestimmt Methode, dann wird die Zeichenfolge aus dem Pool zurückgegeben. Ansonsten, das Das String-Objekt wird zum Pool hinzugefügt und eine Referenz auf diese Zeichenfolge Objekt wird zurückgegeben.
Daraus folgt, dass für zwei beliebige Strings s und t, s.intern () == t.intern () ist genau dann wahr, wenn s.equals (t) wahr ist.
Alle Literalstrings und stringwertigen Konstantenausdrücke sind interniert. String-Literale sind in §3.10.5 der Java-Sprache definiert Spezifikation
Die internalisierten Zeichenfolgen befinden sich im Bereich "Perm Gen" und bei String-Objekten, die von .intern()
zurückgegeben werden, können Sie den Operator ==
verwenden, da .intern()
immer das gleiche Objekt für gleiche Werte zurückgibt.
Denken Sie daran, dass die Methode .intern()
keine Lecks produziert, weil die JVM heute in der Lage ist, den Pool zu löschen.
Versuchen Sie, auch diesen Artikel zu lesen.
Unabhängig von der Internierung verwendet Java String das Fliegengewichtmuster, indem es die char[]
zwischen einer Zeichenkette und den daraus abgeleiteten Zeichenketten über substring
und ähnliche Methodenaufrufe teilt. Dies hat jedoch eine Kehrseite: Wenn Sie eine kleine Teilzeichenfolge einer großen Zeichenfolge verwenden, ist die riesige char[]
nicht für die Garbage Collection geeignet.
Hinweis: ab der OpenJDK-Version 1.7.0_06 obiges ist obsolet geworden: Der Code wurde geändert, so dass das char[]
nicht mehr zwischen den Instanzen geteilt wird. substring()
erstellt ein neues Array.
Sie haben richtig erkannt, dass sowohl das Internieren als auch das Fliegengewicht auf der gleichen Idee basieren: Zwischenspeichern und gemeinsame Nutzung des gemeinsamen Status. Bei einem Fliegengewicht besteht im Extremfall, in dem es keinen intrinsischen Zustand zum Speichern gibt, keine Notwendigkeit, dass das Objekt existiert. Nur der Zeiger auf den extrinsischen Zustand bleibt übrig, und dann ist Fliegengewicht zu Interning geworden.
Ob Internieren "wirklich" eine Art Fliegengewicht ist oder nicht, ist nur eine Debatte über Definitionen. Was am wichtigsten ist, ist das Verständnis, wie man als eine spezialisierte Instanz des anderen angesehen werden kann, also bist du gut.
Genau wie andere bereits erwähnt haben, geht es bei String.intern () um Caching. Es gibt den Verweis auf bereits gespeichertes Zeichenfolgenliteral im Pool zurück. Auf diese Weise ähnelt es irgendwie dem Flightweight-Muster, da es die vorhandenen Objekte verwendet, was zu einem geringeren Speicherverbrauch und einer erhöhten Leistung führt (obwohl intern auch die eigenen Leistungseinbußen bei der Suche im String-Pool bestehen). Daher können diese beiden ähnlich erscheinen, sind es aber nicht.
Bei Flyweight handelt es sich darum, die internen Komponenten des Objekts zu teilen. Beim Internieren werden nur die gesamten Objekte zwischengespeichert.
Tags und Links java design-patterns flyweight-pattern