使用不可序列化的对象序列化hashmap

时间:2014-01-21 10:40:06

标签: java serialization hashmap javafx components

如何序列化包含不可序列化对象的哈希映射,在我的案例中是JavaFX组件?

final HashMap<String, Button> mapButton = new HashMap<>();
// some for loop adding the components..
try {
     FileOutputStream fileOut = new FileOutputStream("Resources/");
     ObjectOutputStream objStream = new ObjectOutputStream(fileOut);
     objStream.writeObject(mapButton);
     objStream.close();
     fileOut.close();
     System.out.println("Serialized HashMap mapButtons has been stored"
                         + " in /tmp/store");
    } catch (IOException i) {
          i.printStackTrace();
    }

抛出:

  

java.io.NotSerializableException:javafx.scene.control.Button

3 个答案:

答案 0 :(得分:2)

如果要序列化对象,则必须Serializable

由于javafx.scene.control.Button不可序列化,您必须找到另一种方法将按钮的状态保存在其他位置。例如。通过介绍保护国家的纪念品类:

public class ButtonMemento implements Serializable {

       private static final long serialVersionUID = 1L;

       private boolean text;

       /*
        * Creates a memento that safes the given button's current state.
        */
       public ButtonMemento(Button button){
             this.text = button.getText();
            // extend to record more properties of the button
       }

       /*
        * Used to apply the current mementos state to a button
        */
       public void applyState(Button button){
           button.setText(text);
           // extend to apply more properties to the button
       }
}

ButtonMemento类是一种保护不可序列化的对象状态并在以后恢复的方法。

final HashMap<String, ButtonMemento> mapButton = new HashMap<>();

for(Button b : buttons){
    String mapKey = ...;
    mapButton.put(mapKey, new ButtonMemento(b));
}    

try {
    FileOutputStream fileOut = new FileOutputStream("Resources/");
    ObjectOutputStream objStream = new ObjectOutputStream(fileOut);
    objStream.writeObject(mapButton);
    objStream.close();
    fileOut.close();
    System.out.println("Serialized HashMap mapButtons has been stored"
                     + " in /tmp/store");
} catch (IOException i) {
      i.printStackTrace();
}

也许你可以实现像BeanMemento这样的东西,它可以存储可序列化的bean的属性,因此可以用于满足java bean规范的每个对象。

答案 1 :(得分:1)

duplicate

您应该在班级上实施readObjectwriteObject,以便您可以自定义方式对其对象进行序列化。

  • 首先,制作不可序列的字段transient
  • writeObject中,首先在流上调用defaultWriteObject以存储所有非瞬态字段,然后调用其他方法来序列化不可序列化对象的各个属性。
  • readObject中,首先在流上调用defaultReadObject以回读所有非瞬态字段,然后调用其他方法(对应于您添加到writeObject的方法)进行反序列化你的不可串行的对象。

我希望这是有道理的。 : - )

答案 2 :(得分:1)

您可以在Button周围创建一个可序列化的包装器,并在其中实现自定义序列化。您将在writeObject中保存按钮属性,读取它们并在readObject中重新创建按钮