2017-11-15 2 views
0

Gemäß this document sind die Felder der Enum-Konstanten nicht serialisiert. Also habe ich die folgende Demo zusammen:Warum werden meine enum-Felder serialisiert?

import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 

enum EnumBasedSingleton 
{ 
    INSTANCE; 

    EnumBasedSingleton() { 
    value = 42; 
    } 

    int value; 

    public int getValue() 
    { 
    return value; 
    } 
    public void setValue(int value) 
    { 
    this.value = value; 
    } 
} 

class EnumBasedSingletonDemo 
{ 
    static void saveToFile(EnumBasedSingleton singleton, String filename) 
    throws Exception 
    { 
    try (FileOutputStream fileOut = new FileOutputStream(filename); 
     ObjectOutputStream out = new ObjectOutputStream(fileOut)) 
    { 
     out.writeObject(singleton); 
    } 
    } 

    static EnumBasedSingleton readFromFile(String filename) 
    throws Exception 
    { 
    try (FileInputStream fileIn = new FileInputStream(filename); 
     ObjectInputStream in = new ObjectInputStream(fileIn)) 
    { 
     return (EnumBasedSingleton)in.readObject(); 
    } 
    } 

    public static void main(String[] args) 
    throws Exception 
    { 
    EnumBasedSingleton singleton = EnumBasedSingleton.INSTANCE; 
    singleton.setValue(111); 
    String filename = "myfile.bin"; 
    saveToFile(singleton, filename); 
    EnumBasedSingleton singleton2 = readFromFile(filename); 
    System.out.println(singleton2.getValue()); 
    } 
} 

ich die Ausgabe erwartete 42 zu sein, aber was ich habe ist 111. Missverstehe ich das Dokument oder sind Felder von Enum-Konstanten serialisiert? Ich verwende dies in Java 9.

+0

Warum haben Sie 42 erwartet? – shmosel

+0

@smossel, weil der Konstruktor diesen Wert angibt –

+1

Enums sind Singletons. Das Dokument sagt _Die serialisierte Form einer Enum-Konstante besteht nur aus ihrem Namen _ Es folgt, dass während der Deserialisierung der Name verwendet wird, um die Enum-Konstante anhand des Namens zu bestimmen. Diese Enum-Konstante hat in Ihrem aktuellen Prozess einen Wert von 111. Es wird kein Konstruktor aufgerufen. –

Antwort

0

Es gibt nur eine Instanz einer enum Konstante während der Lebensdauer eines Java-Prozesses.

Das Dokument verknüpft Staaten

Die serialisierte Form einer enum konstant allein ihres Namens besteht; Feldwerte der Konstante sind in der Form nicht vorhanden. Um eine Konstante enum zu serialisieren, schreibt ObjectOutputStream den Wert, der von der enum Konstanten name Methode zurückgegeben wird. Um eine enum Konstante zu deserialisieren, liest ObjectInputStream den konstanten Namen aus dem Strom; Die deserialisierte Konstante wird dann durch Aufrufen der java.lang.Enum.valueOf-Methode erhalten, wobei der enum-Typ der Konstanten mit dem empfangenen konstanten Namen als Argumente an übergeben wird.

Mit anderen Worten, der Name der Konstante wird verwendet, um die entsprechende Instanz abzurufen. Diese Instanz ist jedoch dieselbe Instanz, die Sie serialisiert haben. Es handelt sich nicht um eine neue Instanz. Der Konstruktor enum wurde nicht erneut aufgerufen. Und da Sie den Zustand der enum Konstante früher geändert haben, sehen Sie diesen geänderten Wert.

Haben Sie einen neuen Java-Prozess und versuchten, begannen den Inhalt dieser Datei deserialisieren ohne Berührung die enum konstant, würden Sie 42 seinen ursprünglichen Wert von


Das Mißverständnis wandelbaren Stammzellen könnte gesehen haben von der Verwendung in deinen enums angeben. That's strongly discouraged.

Verwandte Themen