---
# System prepended metadata

title: Serialization
tags: [Java]

---

# Serialization
序列化, 用於把一個instance轉為byte stream, 
並且可以把byte stream用 網路/檔案 傳送,再進行反序列化, 還原instance.
    
假設我們有一個class叫做Person,
想要要對他的instance進行序列化, 直接實作Serializable接口
```java=
public class Person implements Serializable {
    private final int id;
    private final String name;

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }
    
    @Override
    public String toString() {
        return "Person{id=" + id + ", name=" + name + "}";
    }
}
```
## Serialize
使用ObjectOutputStream把物件write到某個地方, 例如檔案(File)
```java=
public static void main(String[] args) {
    Person p = new Person(19,"andy");

    FileOutputStream fileOut = new FileOutputStream("test.txt");
    ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
    objectOut.writeObject(p);
    objectOut.close();
    fileOut.close();
}
```
    
## Unserialize
```java=
public static void main(String[] args) {
    FileInputStream fileIn = new FileInputStream("test.txt");
    ObjectInputStream objectIn = new ObjectInputStream(fileIn);
    Person p = (Person) objectIn.readObject();
    objectIn.close();
    fileIn.close();
    
    System.out.println(p); // Person{id=19, name=andy}
}
```
### SerialVersionId
可以在Serializable裡放一個serialVersionUID (long)
    
序列化時,id會被寫入stream中
反序列化時,id會跟反序列class的id比對
如果不同, 丟出InvalidClassException
    
總之, **序列化class的id 與 反序列化class的id 必須相同**
    
預設是會自動按照class member生成SerialVersionId, 但也可以自己寫。
```java=
    
public class Person implements Serializable {
    
    @Serial 
    private static final long serialVersionUID = 1000000L;
    
    //...
}
```