- 除了被標示為transient的variable不會儲存外,其他都會被儲存
- 必須藉由implements Serializable interface來明確選擇哪些object可以被serialize
- implements Serializable不需要override任何methods
- 若有沒辦法implements Serializable interface(比如class設定成final無法修改)的情況下且需要儲存狀態,需要自行實作writeObject()或 readObject(),例:
class Dog implements Serializable { transient private Collar theCollar; // 不能序列化它 private int dogSize,自行實作 public Dog(Collar collar, int size) { theCollar = collar; dogSize = size; } public Collar getCollar() { return theCollar; } private void writeObject(ObjectOutputStream os) { // override // throws IOException { try { os.defaultWriteObject(); os.writeInt(theCollar.getCollarSize()); // 自行包裝dog size } catch (Exception e) { e.printStackTrace(); } } private void readObject(ObjectInputStream is) { // override // throws IOException, ClassNotFoundException { try { is.defaultReadObject(); theCollar = new Collar(is.readInt());// 自行取出dog size } catch (Exception e) { e.printStackTrace(); } } }
- 若superclass implements Serializable,則所有底下的subclass都會跟著繼承,也就是subclass不需要明確的標示Serializable也能夠存取state
- 若superclass沒有implements Serializable,任何維護在superclass的state(從superclass繼承下來,且沒有override的),都不會回覆,將被重新初始化(就像是跑了一次 superclass的constructor)
- 若使用transient標示變數,代表不需要序列化此值,且該值會被恢復成default值,例:
class TestSer{ public static void main(String[] args){ SpecialSerial s = new SpecialSerial(); try{ ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("myFile")); os.writeObject(s); //s1.y ==7, s1.z == 9 os.close();
ObjectInputStream is = new ObjectInputStream(new FileInputStream("myFile")); SpecialSerial s2 = (SpecialSerial)is.readObject(); is.close(); System.out.println(s2.y + " " + s2.z); // s2.y == 0, s2.z == 10 }catch (Exception e){ System.out.println("exc"); } } } class SpecialSerial implements Serializable{ transient int y = 7; static int z = 9; }
注意:
- 最後output s2.y=0,原因是被標示為transient,不管initial值為何,都會變成該形態的default值
- 因為此例中z是static,代表memory只有存一份記憶體,且和instance無關,是class等級。所以最後取出的時候,值也會跟著變成10。
- 綜合以上兩點代表static&transient 變數所屬的object並不能夠被序列化。
沒有留言:
張貼留言