2017-11-15 5 views
0

this document에 따르면 열거 형 상수의 필드는 serialize되지 않습니다. 그래서 나는 다음과 같은 데모를 함께 넣어 : 나는 42로 출력을 기다리고 있었다열거 형 필드가 직렬화되는 이유는 무엇입니까?

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()); 
    } 
} 

을하지만 내가 가진 것은 111입니다. 내가 문서를 오해하고 있거나 enum 상수의 필드가 직렬화되어 있습니까? Java 9에서 이것을 실행하고 있습니다.

+0

42 세가 예상되는 이유는 무엇입니까? – shmosel

+0

생성자가이 값을 지정하므로 @shmosel –

+1

열거 형은 싱글 톤입니다. 이 문서는 다음과 같이 말합니다 _ enum 상수의 직렬화 된 형식은 이름만으로 구성됩니다. _ 직렬화 중에 이름이 열거 형 상수를 이름으로 결정하는 데 사용됩니다. 해당 enum 상수는 현재 프로세스에서 111의 값을가집니다. 생성자가 호출되지 않습니다. –

답변

0

Java 프로세스의 수명 동안 enum 상수는 하나만 있습니다.

문서는 연결 상태

enum 정수의 직렬화 된 형식을 구성하는 것은, 그 이름뿐입니다 상수의 필드 값이 양식에 없습니다. 을 enum 상수로 serialize하려면 ObjectOutputStream은 메서드의 enum 메서드에서 반환 된 값을 씁니다. enum 상수를 비 직렬화하려면 ObjectInputStream은 스트림에서 상수 이름을 읽습니다. 그런 다음 직렬화 된 상수는 java.lang.Enum.valueOf 메서드를 호출하고 상수의 enum 유형을 과 함께 수신 된 상수 이름을 인수로 사용하여 얻습니다.

즉, 상수의 이름은 적절한 인스턴스를 검색하는 데 사용됩니다. 그러나이 인스턴스는 사용자가 직렬화 한 동일한 인스턴스이고 새로운 인스턴스는 아니며 enum 생성자가 다시 호출되지 않았습니다. 그리고 이전에 enum 상태를 변경 했으므로 변경된 값이 표시됩니다.

당신이, 당신이 오해가 변경 가능한 사용에서 줄기 수 (42)


의 원래 값을 보았을 것 새로운 자바 프로세스를 시작하고 enum 상수를 건드리지 않고 해당 파일의 내용을 역 직렬화하려고했다 귀하의 enums에 상태. That's strongly discouraged.