2014-03-12 44 views
1

我不明白如何在序列化類時處理依賴字段的一般原則。如何在序列化時處理依賴字段?

字段顯示相互依賴的模式很多。例如,下面我正在爲構造函數中的列表創建一個可觀察的包裝器。創建時,包裝器將依賴字段幷包裝它。

這個類在Gson和默認Java解串器中都沒有反序列化。

Gson它調用默認的構造函數,它首先建立鏈接。但後來Gsondelegate成員創建新實例,因爲observable現在引用過時的對象,所以會中斷鏈接。

我不明白,Gson創造者調用默認構造函數,如果他們後來放棄它的功能?他們是否認爲每個班級都可以在直接外派任務中生存?

Java默認序列化也不起作用。他們只是忽略瞬態場,它仍然是空的。構造函數沒有被調用。

我也不明白:如果他們不調用構造函數,那他們爲什麼不假定Serializable接口有一些構造函數等價的方法,應該在反序列化之後調用?

package tests; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.FileReader; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.Serializable; 
import java.util.ArrayList; 

import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 

import com.google.gson.Gson; 
import com.google.gson.GsonBuilder; 
import com.google.gson.JsonIOException; 

public class Try05 { 

    public static class MyList implements Serializable { 

     private static final long serialVersionUID = 7048098048856503023L; 

     ArrayList<Integer> delegate = new ArrayList<Integer>(); 
     transient ObservableList<Integer> observable = FXCollections.observableList(delegate); 

     public void add(int value) { 
      observable.add(value); 
     } 

     public int sum() { 
      int ans = 0; 
      for (Integer i : observable) { 
       ans += i.intValue(); 
      } 
      return ans; 
     } 

     @Override 
     public String toString() { 
      return delegate.toString(); 
     } 

    } 

    public static void tryGson() throws JsonIOException, IOException { 

     Gson gson = new GsonBuilder().enableComplexMapKeySerialization().serializeNulls().setPrettyPrinting().setVersion(1.0) 
       .create(); 

     MyList list = new MyList(); 

     list.add(12); 
     list.add(13); 

     System.out.println(String.format("list = %s, sum = %d", list.toString(), list.sum())); 
     System.out.println(String.format("hash = %d", System.identityHashCode(list.delegate))); 

     File file = File.createTempFile("list", ".json"); 

     FileWriter writer = new FileWriter(file); 
     gson.toJson(list, writer); 
     writer.flush(); 
     writer.close(); 

     list = gson.fromJson(new FileReader(file), MyList.class); 

     list.add(14); 

     System.out.println(String.format("list = %s, sum = %d", list.toString(), list.sum())); 
     System.out.println(String.format("hash = %d", System.identityHashCode(list.delegate))); 

    } 

    public static void tryBuiltin() throws IOException, ClassNotFoundException { 

     MyList list = new MyList(); 

     list.add(12); 
     list.add(13); 

     System.out.println(String.format("list = %s, sum = %d", list.toString(), list.sum())); 
     System.out.println(String.format("hash = %d", System.identityHashCode(list.delegate))); 

     File file = File.createTempFile("list", ".json"); 

     ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file)); 
     out.writeObject(list); 
     out.flush(); 
     out.close(); 

     ObjectInputStream in = new ObjectInputStream(new FileInputStream(file)); 
     list = (MyList) in.readObject(); 

     list.add(14); 

     System.out.println(String.format("list = %s, sum = %d", list.toString(), list.sum())); 
     System.out.println(String.format("hash = %d", System.identityHashCode(list.delegate))); 

    } 


    public static void main(String[] args) { 

     try { 

      tryGson(); 

      tryBuiltin(); 

     } catch (JsonIOException | IOException | ClassNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 



    } 


} 

回答

1

您對不包含Serializable接口呼籲deserialisation方法是不正確的說法 - 有;使用默認的Java序列化,你可以聲明一個特殊的方法,在讀取你的對象時被調用。它看起來像這樣:

private /* or any other access modifier */ void readObject(ObjectInputStream in) throws IOException { 
    // your code here 
} 

在這種情況下,這種方法的內容是這樣的:

in.defaultReadObject(); // invoke default read 
observable = FXCollections.observableList(delegate); // initialise observable 

有關該法和其他方法的詳細信息,看Serializable類的規範: http://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html