如何序列化包含不可序列化对象的哈希映射,在我的案例中是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
答案 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)
您应该在班级上实施readObject
和writeObject
,以便您可以自定义方式对其对象进行序列化。
transient
。writeObject
中,首先在流上调用defaultWriteObject
以存储所有非瞬态字段,然后调用其他方法来序列化不可序列化对象的各个属性。readObject
中,首先在流上调用defaultReadObject
以回读所有非瞬态字段,然后调用其他方法(对应于您添加到writeObject
的方法)进行反序列化你的不可串行的对象。我希望这是有道理的。 : - )
答案 2 :(得分:1)
您可以在Button周围创建一个可序列化的包装器,并在其中实现自定义序列化。您将在writeObject中保存按钮属性,读取它们并在readObject中重新创建按钮