2014-01-21 64 views
1

如何序列化包含不可序列化對象的hashmap,在我的情況下是JavaFX組件?使用不可序列化對象序列化hashmap

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

+2

您不能序列化不可序列化的對象。期。 – Pietu1998

+0

你看,HashMap對象本身實際上是可序列化的,只有它包含的對象不是。所以我認爲這可能是可能的。 – Taerus

+0

是的,但是HashMap如何序列化它的項目呢? – Pietu1998

回答

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

duplicate

你應該實現你的類readObjectwriteObject所以你可以以自定義的方式將其對象序列化。

  • 首先,使您的不可序列化字段transient
  • writeObject中,首先調用defaultWriteObject來存儲所有非瞬態字段,然後調用其他方法來序列化不可序列化對象的各個屬性。
  • readObject中,首先在流上調用defaultReadObject來回讀所有非瞬態字段,然後調用其他方法(對應於您添加到writeObject的那些方法)來對您的不可序列化對象進行反序列化。

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

1

您可以在Button周圍創建一個可序列化的包裝器並在其中實現自定義序列化。您將在writeObject中保存按鈕屬性,將它們讀回並在readObject中重新創建按鈕