熟悉Java的朋友應該知道Java有一個叫序列化的技術,即把一個Object轉換為可保存,可傳輸的流數據。相應的,同時存在反序列化,即將流數據轉換為Object類,而在轉換的過程中,該Object保持者其自身的狀態。不會應該序列化或者反序列化而丟失。通常在緩存中,RPC(遠程調用),或者長久保存會話信息時,大有用處。
關于序列化的時候,大部分情況下想到的是對于需要序列化的對象實現Serializable標志接口,同時為該對象提供一個唯一的serialVersionUID。
示例代碼
public class Person implements Serializable { private static final long serialVersionUID = -763618247875550322L; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; public class WhySerialversionUID { public static void main(String[] args) throws Exception { //這里是把對象序列化到文件 Person crab = new Person(); crab.setName("kaka"); ObjectOutputStream oo = new ObjectOutputStream (new FileOutputStream("kakaFile")); oo.writeObject(crab); oo.close(); //這里是把文件序列化到對象 ObjectInputStream oi = new ObjectInputStream (new FileInputStream("kakaFile")); Person kaka = (Person) oi.readObject(); //輸出為Hi, My name is kaka System.out.println("Hi, My name is " + kaka.getName()); oi.close(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
看起來使用JDK提供的序列化技術沒有什么問題,其實不然。JDK提供的序列化技術相對而已效率較低。在轉換二進制數組過程中空間利用率較差。github上有個專門對比序列化技術做對比的數據:https://github.com/eishay/jvm-serializers/wiki
其中看的出來性能最優的為google開發的colfer 。這個框架盡管性能優秀,但它太過于靈活,靈活到Schema都要開發者自己指定,所以對開發者不是很友好。我推薦使用Protostuff,其性能稍弱與colfer,但對開發者很友好,同時性能遠遠高于JDK提供的Serializable。
java中如何實現序列化,添加依賴:
<dependency><groupId>io.protostuff</groupId> <artifactId>protostuff-core</artifactId> <version>1.4.4</version> </dependency> <dependency> <groupId>io.protostuff</groupId> <artifactId>protostuff-runtime</artifactId> <version>1.4.4</version> </dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
簡單使用:
private static RuntimeSchema<Person> schema = RuntimeSchema.createFrom(Person.class);
/**
*序列化
*/
Person crab = new Person();
crab.setName("kaka"); //參數三緩沖器 byte[] bytes = ProtostuffIOUtil.toByteArray(crab,schema,LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE)); /** *反序列化 */ // 空對象 Person newCrab = schema.newMessage(); ProtostuffIOUtil.mergeFrom(bytes,newCrab,schema); System.out.println("Hi, My name is " + newCrab.getName());
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15