Ich habe gerade ein paar Stunden mit dem Debuggen meiner App verloren, und ich glaube, ich bin auf einen (anderen o_O) Java Bug gestoßen ... schnüffle ... ich hoffe es ist nicht, denn das wäre traurig : (
Ich mache folgendes:
mask
mit einigen Flags ObjectOutputStream.writeObject(mask)
) mask
Erwartetes Ergebnis: Das zweite serialisierte Objekt unterscheidet sich von dem ersten (spiegelt die Änderungen in der Instanz wider)
Ergebnis erhalten: das zweite serialisierte Objekt ist die genaue Kopie des ersten serialisierten Objekts
Der Code:
%Vor%Es druckt:
%Vor%
Verwende ich EnumSet
falsch? Muss ich jedes Mal eine neue Instanz erstellen, anstatt sie zu löschen?
Danke für Ihre Eingabe!
**** UPDATE ****
Meine ursprüngliche Idee war es, ein EnumSet
als Maske zu verwenden, um anzugeben, welche Felder in der folgenden Nachricht vorhanden oder abwesend sein werden, also eine Art Optimierung der Bandbreite und der CPU-Nutzung. Es war sehr falsch !!! Ein EnumSet
braucht Zeitalter, um zu serialisieren, und jede Instanz benötigt 30 (!!!) Bytes! So viel zur Weltraumwirtschaft :)
Kurz gesagt, während ObjectOutputStream
für primitive Typen sehr schnell ist (wie ich bereits in einem kleinen Test herausgefunden habe: Ссылка
Also habe ich daran gearbeitet, indem ich mein eigenes EnumSet erstellt habe, das von einem int unterstützt wird, und das int direkt serialisieren / deserialisieren (nicht das Objekt).
%Vor%Es ist etwa 130 mal schneller während der Serialisierung und 25 mal schneller während der Deserialisierung ...
MyEnumSets:
%Vor%
Reguläre EnumSets:
%Vor%
Es ist jedoch nicht so sicher. Zum Beispiel funktioniert es nicht für Enums mit mehr als 32 Einträgen.
Wie kann ich sicherstellen, dass die Enumeration weniger als 32 Werte für MyEnumSet-Erstellung hat?
ObjectOutputStream serialisiert Verweise auf Objekte und beim ersten Senden eines Objekts das tatsächliche Objekt. Wenn Sie ein Objekt ändern und erneut senden, sendet alle ObjectOutputStream die Referenz erneut an dieses Objekt.
Das hat ein paar Konsequenzen
Um dies zu beheben und etwas Speicher zurück zu bekommen, rufen Sie Zurücksetzen () nach jedem vollständigen Objekt. z.B. vor dem Aufruf von flush()
Reset ignoriert den Status von Objekten, die bereits in den Stream geschrieben wurden. Der Status wird so zurückgesetzt, dass er einem neuen ObjectOutputStream entspricht. Der aktuelle Punkt im Stream wird als zurückgesetzt markiert, sodass der entsprechende ObjectInputStream am selben Punkt zurückgesetzt wird. Objekte, die zuvor in den Stream geschrieben wurden, werden nicht als bereits im Stream befindlich bezeichnet. Sie werden wieder in den Stream geschrieben.
Ein anderer Ansatz besteht darin, writeUnshared zu verwenden , jedoch gilt dies für das Toplevel-Objekt mit einer flachen Unsharedness. Im Falle von EnumSet
wird es anders sein, aber die Enum[]
Wraps sind immer noch geteilt o_O
Schreibt ein "nicht gemeinsam verwendetes" Objekt in den ObjectOutputStream. Diese Methode ist identisch mit writeObject, außer dass das angegebene Objekt immer als neues, eindeutiges Objekt im Stream geschrieben wird (im Gegensatz zu einer Rückreferenz, die auf eine zuvor serialisierte Instanz verweist).
Kurz gesagt, nein, das ist kein Fehler, sondern erwartetes Verhalten.
Tags und Links java serialization enumset