使用不可序列化的对象序列化 hashmap
Posted
技术标签:
【中文标题】使用不可序列化的对象序列化 hashmap【英文标题】:Serialize hashmap with non-serializable objects 【发布时间】:2014-02-10 21:41:13 【问题描述】:我如何序列化包含不可序列化对象的哈希映射,在我的例子中是 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
【问题讨论】:
你不能序列化不可序列化的对象。期间。 你看,HashMap 对象本身实际上是可序列化的,只有它包含的对象不是。因此我认为这是可能的。 是的,但是HashMap如何序列化它的项目? 【参考方案1】:如果你想序列化对象,它们必须是Serializable
。
由于javafx.scene.control.Button
不可序列化,您必须找到另一种方法将按钮的状态保存在其他位置。例如。通过引入一个保护状态的 memento 类:
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 规范的每个对象一起使用。
【讨论】:
【参考方案2】:duplicate
您应该在您的类上实现readObject
和writeObject
,以便您可以以自定义方式序列化其对象。
transient
。
在writeObject
中,首先在流上调用defaultWriteObject
以存储所有非瞬态字段,然后调用其他方法来序列化不可序列化对象的各个属性。
在readObject
中,首先在流上调用defaultReadObject
以读取所有非瞬态字段,然后调用其他方法(对应于您添加到writeObject
的方法)来反序列化您的不可序列化对象。
我希望这是有道理的。 :-)
【讨论】:
【参考方案3】:您可以围绕 Button 创建一个可序列化的包装器并在其中实现自定义序列化。您将在 writeObject 中保存按钮属性,读取它们并在 readObject 中重新创建按钮
【讨论】:
以上是关于使用不可序列化的对象序列化 hashmap的主要内容,如果未能解决你的问题,请参考以下文章