一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java實現幾種序列化方式總結

Java實現幾種序列化方式總結

2020-08-24 10:38皮斯特勞沃 Java教程

本篇文章主要介紹了Java實現幾種序列化方式總結,包括Java原生以流的方法進行的序列化、Json序列化、FastJson序列化、Protobuff序列化。有興趣的可以了解一下。

0、前言

本文主要對幾種常見Java序列化方式進行實現。包括Java原生以流的方法進行的序列化、Json序列化、FastJson序列化、Protobuff序列化。

1、Java原生序列化

Java原生序列化方法即通過Java原生流(InputStream和OutputStream之間的轉化)的方式進行轉化。需要注意的是JavaBean實體類必須實現Serializable接口,否則無法序列化。Java原生序列化代碼示例如下所示:

?
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package serialize;
 
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
/**
 *
 * @author liqqc
 *
 */
public class JavaSerialize {
  public static void main(String[] args) throws ClassNotFoundException, IOException {
    new JavaSerialize().start();
  }
 
  public void start() throws IOException, ClassNotFoundException {
    User u = new User();
    List<User> friends = new ArrayList<>();
    u.setUserName("張三");
    u.setPassWord("123456");
    u.setUserInfo("張三是一個很牛逼的人");
    u.setFriends(friends);
 
    User f1 = new User();
    f1.setUserName("李四");
    f1.setPassWord("123456");
    f1.setUserInfo("李四是一個很牛逼的人");
 
    User f2 = new User();
    f2.setUserName("王五");
    f2.setPassWord("123456");
    f2.setUserInfo("王五是一個很牛逼的人");
 
    friends.add(f1);
    friends.add(f2);
 
    Long t1 = System.currentTimeMillis();
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ObjectOutputStream obj = new ObjectOutputStream(out);
    for(int i = 0; i<10; i++) {
      obj.writeObject(u);
    }
    System.out.println("java serialize: " +(System.currentTimeMillis() - t1) + "ms; 總大小:" + out.toByteArray().length );
 
    Long t2 = System.currentTimeMillis();
    ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new java.io.ByteArrayInputStream(out.toByteArray())));
    User user = (User) ois.readObject();
    System.out.println("java deserialize: " + (System.currentTimeMillis() - t2) + "ms; User: " + user);
  }
 
}

運行結果:

java serialize: 8ms; 總大小:420

 

復制代碼 代碼如下:

java deserialize: 1ms; User: User [userId=null, userName=張三, passWord=123456, userInfo=張三是一個很牛逼的人, friends=[User [userId=null, userName=李四, passWord=123456, userInfo=李四是一個很牛逼的人, friends=null], User [userId=null, userName=王五, passWord=123456, userInfo=王五是一個很牛逼的人, friends=null]]]

 

2、Json序列化

Json序列化一般會使用jackson包,通過ObjectMapper類來進行一些操作,比如將對象轉化為byte數組或者將json串轉化為對象。現在的大多數公司都將json作為服務器端返回的數據格式。比如調用一個服務器接口,通常的請求為xxx.json?a=xxx&b=xxx的形式。Json序列化示例代碼如下所示:

?
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package serialize;
 
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
import com.fasterxml.jackson.databind.ObjectMapper;
/**
 *
 * @author liqqc
 *
 */
public class JsonSerialize {
  public static void main(String[] args) throws IOException {
    new JsonSerialize().start();
  }
 
  public void start() throws IOException {
    User u = new User();
    List<User> friends = new ArrayList<>();
    u.setUserName("張三");
    u.setPassWord("123456");
    u.setUserInfo("張三是一個很牛逼的人");
    u.setFriends(friends);
 
    User f1 = new User();
    f1.setUserName("李四");
    f1.setPassWord("123456");
    f1.setUserInfo("李四是一個很牛逼的人");
 
    User f2 = new User();
    f2.setUserName("王五");
    f2.setPassWord("123456");
    f2.setUserInfo("王五是一個很牛逼的人");
 
    friends.add(f1);
    friends.add(f2);
 
    ObjectMapper mapper = new ObjectMapper();
    Long t1 = System.currentTimeMillis();
    byte[] writeValueAsBytes = null;
    for (int i = 0; i < 10; i++) {
      writeValueAsBytes = mapper.writeValueAsBytes(u);
    }
    System.out.println("json serialize: " + (System.currentTimeMillis() - t1) + "ms; 總大小:" + writeValueAsBytes.length);
    Long t2 = System.currentTimeMillis();
    User user = mapper.readValue(writeValueAsBytes, User.class);
    System.out.println("json deserialize: " + (System.currentTimeMillis() - t2) + "ms; User: " + user);
 
  }
}

運行結果:

json serialize: 55ms; 總大小:341

 

復制代碼 代碼如下:

json deserialize: 35ms; User: User [userId=null, userName=張三, passWord=123456, userInfo=張三是一個很牛逼的人, friends=[User [userId=null, userName=李四, passWord=123456, userInfo=李四是一個很牛逼的人, friends=null], User [userId=null, userName=王五, passWord=123456, userInfo=王五是一個很牛逼的人, friends=null]]]

 

3、FastJson序列化

fastjson 是由阿里巴巴開發的一個性能很好的Java 語言實現的 Json解析器和生成器。特點:速度快,測試表明fastjson具有極快的性能,超越任其他的Java json parser。功能強大,完全支持java bean、集合、Map、日期、Enum,支持范型和自省。無依賴,能夠直接運行在Java SE 5.0以上版本

支持Android。使用時候需引入FastJson第三方jar包。FastJson序列化代碼示例如下所示:

?
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package serialize;
 
import java.util.ArrayList;
import java.util.List;
 
import com.alibaba.fastjson.JSON;
/**
 *
 * @author liqqc
 *
 */
public class FastJsonSerialize {
 
  public static void main(String[] args) {
    new FastJsonSerialize().start();
  }
 
  public void start(){
    User u = new User();
    List<User> friends = new ArrayList<>();
    u.setUserName("張三");
    u.setPassWord("123456");
    u.setUserInfo("張三是一個很牛逼的人");
    u.setFriends(friends);
 
    User f1 = new User();
    f1.setUserName("李四");
    f1.setPassWord("123456");
    f1.setUserInfo("李四是一個很牛逼的人");
 
    User f2 = new User();
    f2.setUserName("王五");
    f2.setPassWord("123456");
    f2.setUserInfo("王五是一個很牛逼的人");
 
    friends.add(f1);
    friends.add(f2);
 
    //序列化
    Long t1 = System.currentTimeMillis();
    String text = null;
    for(int i = 0; i<10; i++) {
      text = JSON.toJSONString(u);
    }
    System.out.println("fastJson serialize: " +(System.currentTimeMillis() - t1) + "ms; 總大小:" + text.getBytes().length);
    //反序列化
    Long t2 = System.currentTimeMillis();
    User user = JSON.parseObject(text, User.class);
    System.out.println("fastJson serialize: " + (System.currentTimeMillis() -t2) + "ms; User: " + user);
  }
}

運行結果:

fastJson serialize: 284ms; 總大小:269

 

復制代碼 代碼如下:

fastJson serialize: 26ms; User: User [userId=null, userName=張三, passWord=123456, userInfo=張三是一個很牛逼的人, friends=[User [userId=null, userName=李四, passWord=123456, userInfo=李四是一個很牛逼的人, friends=null], User [userId=null, userName=王五, passWord=123456, userInfo=王五是一個很牛逼的人, friends=null]]]

 

4、ProtoBuff序列化

ProtocolBuffer是一種輕便高效的結構化數據存儲格式,可以用于結構化數據序列化。適合做數據存儲或 RPC 數據交換格式。可用于通訊協議、數據存儲等領域的語言無關、平臺無關、可擴展的序列化結構數據格式。

優點:跨語言;序列化后數據占用空間比JSON小,JSON有一定的格式,在數據量上還有可以壓縮的空間。

缺點:它以二進制的方式存儲,無法直接讀取編輯,除非你有 .proto 定義,否則無法直接讀出 Protobuffer的任何內容。

其與thrift的對比:兩者語法類似,都支持版本向后兼容和向前兼容,thrift側重點是構建跨語言的可伸縮的服務,支持的語言多,同時提供了全套RPC解決方案,可以很方便的直接構建服務,不需要做太多其他的工作。 Protobuffer主要是一種序列化機制,在數據序列化上進行性能比較,Protobuffer相對較好。

ProtoBuff序列化對象可以很大程度上將其壓縮,可以大大減少數據傳輸大小,提高系統性能。對于大量數據的緩存,也可以提高緩存中數據存儲量。原始的ProtoBuff需要自己寫.proto文件,通過編譯器將其轉換為java文件,顯得比較繁瑣。百度研發的jprotobuf框架將Google原始的protobuf進行了封裝,對其進行簡化,僅提供序列化和反序列化方法。其實用上也比較簡潔,通過對JavaBean中的字段進行注解就行,不需要撰寫.proto文件和實用編譯器將其生成.java文件,百度的jprotobuf都替我們做了這些事情了。

一個帶有jprotobuf注解的JavaBean如下所示,如果你想深入學習可以參照https://github.com/google/protobuf

?
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package serialize;
 
import java.io.Serializable;
import java.util.List;
import com.baidu.bjf.remoting.protobuf.FieldType;
import com.baidu.bjf.remoting.protobuf.annotation.Protobuf;
 
public class User implements Serializable {
  private static final long serialVersionUID = -7890663945232864573L;
 
  @Protobuf(fieldType = FieldType.INT32, required = false, order = 1)
  private Integer userId;
 
  @Protobuf(fieldType = FieldType.STRING, required = false, order = 2)
  private String userName;
 
  @Protobuf(fieldType = FieldType.STRING, required = false, order = 3)
  private String passWord;
 
  @Protobuf(fieldType = FieldType.STRING, required = false, order = 4)
  private String userInfo;
 
  @Protobuf(fieldType = FieldType.OBJECT, required = false, order = 5)
  private List<User> friends;
 
  public Integer getUserId() {
    return userId;
  }
 
  public void setUserId(Integer userId) {
    this.userId = userId;
  }
 
  public String getUserName() {
    return userName;
  }
 
  public void setUserName(String userName) {
    this.userName = userName;
  }
 
  public String getPassWord() {
    return passWord;
  }
 
  public void setPassWord(String passWord) {
    this.passWord = passWord;
  }
 
  public String getUserInfo() {
    return userInfo;
  }
 
  public void setUserInfo(String userInfo) {
    this.userInfo = userInfo;
  }
 
  public List<User> getFriends() {
    return friends;
  }
 
  public void setFriends(List<User> friends) {
    this.friends = friends;
  }
 
  @Override
  public String toString() {
    return "User [userId=" + userId + ", userName=" + userName + ", passWord=" + passWord + ", userInfo=" + userInfo
        + ", friends=" + friends + "]";
  }
 
}

jprotobuf序列化代碼示例如下所示:

?
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package serialize;
 
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
import com.baidu.bjf.remoting.protobuf.Codec;
import com.baidu.bjf.remoting.protobuf.ProtobufProxy;
/**
 *
 * @author liqqc
 *
 */
public class ProtoBuffSerialize {
 
  public static void main(String[] args) throws IOException {
    new ProtoBuffSerialize().start();
  }
 
  public void start() throws IOException {
    Codec<User> studentClassCodec = ProtobufProxy.create(User.class, false);
 
    User u2 = new User();
    List<User> friends = new ArrayList<>();
    u2.setUserName("張三");
    u2.setPassWord("123456");
    u2.setUserInfo("張三是一個很牛逼的人");
    u2.setFriends(friends);
 
    User f1 = new User();
    f1.setUserName("李四");
    f1.setPassWord("123456");
    f1.setUserInfo("李四是一個很牛逼的人");
 
    User f2 = new User();
    f2.setUserName("王五");
    f2.setPassWord("123456");
    f2.setUserInfo("王五是一個很牛逼的人");
    friends.add(f1);
    friends.add(f2);
 
    Long stime_jpb_encode = System.currentTimeMillis();
    byte[] bytes = null;
    for(int i = 0; i<10; i++) {
      bytes = studentClassCodec.encode(u2);
    }
    System.out.println("jprotobuf序列化耗時:" + (System.currentTimeMillis() - stime_jpb_encode) + "ms; 總大小:" + bytes.length);
 
    Long stime_jpb_decode = System.currentTimeMillis();
    User user = studentClassCodec.decode(bytes);
    Long etime_jpb_decode = System.currentTimeMillis();
    System.out.println("jprotobuf反序列化耗時:"+ (etime_jpb_decode-stime_jpb_decode) + "ms; User: " + user);
  }
 
}

運行結果:

jprotobuf序列化耗時:9ms; 總大小:148

 

復制代碼 代碼如下:

jprotobuf反序列化耗時:0ms; User: User [userId=null, userName=張三, passWord=123456, userInfo=張三是一個很牛逼的人, friends=[User [userId=null, userName=李四, passWord=123456, userInfo=李四是一個很牛逼的人, friends=null], User [userId=null, userName=王五, passWord=123456, userInfo=王五是一個很牛逼的人, friends=null]]]

 

5、總結

我們通過Main方法來進行對比測試,(但是通過測試發現少量數據無法準確顯示每種序列化方式的優劣,故這里無法給出比較好的答案,僅供參考)。示例代碼如下所示:

?
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
26
27
28
29
package serialize;
 
import java.io.IOException;
 
/**
 * @author liqqc
 */
public class Main {
 
  public static void main(String[] args) throws IOException, ClassNotFoundException {
 
    ProtoBuffSerialize protoBuffSerialize = new ProtoBuffSerialize();
    protoBuffSerialize.start();
 
    System.err.println();
    System.err.println();
 
    JavaSerialize javaSerialize = new JavaSerialize();
    javaSerialize.start();
    System.err.println();
 
    JsonSerialize jsonSerialize = new JsonSerialize();
    jsonSerialize.start();
    System.err.println();
 
    FastJsonSerialize fastJsonSerialize = new FastJsonSerialize();
    fastJsonSerialize.start();
  }
}

運行結果:

jprotobuf序列化耗時:7ms; 總大小:148
jprotobuf反序列化耗時:0ms

java serialize: 6ms; 總大小:420
java deserialize: 1ms

json serialize: 37ms; 總大小:341
json deserialize: 27ms

fastJson serialize: 173ms; 總大小:269
fastJson serialize: 35ms

上面的測試僅供參考,并不能代表通過大量數據進行測試的結果。可以發現:序列化后對象的所占大小上:protobuff序列化所占總大小是最少的;其次是fastJson序列化;最后是json序列化和java原生序列化。對于序列化耗時,上面的測試不準。

還是去看看專業測試分析吧,具體情況可以進去看看https://github.com/eishay/jvm-serializers/wiki

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://blog.csdn.net/pistolove/article/details/60321123

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 免费网站直接进入 | 国产亚洲99影院 | 91香蕉视频在线 | 亚洲精品成人456在线播放 | 国产成人一区二区三区小说 | 亚洲国产成人在线 | 2021精品国夜夜天天拍拍 | 91视频完整版 | 秋葵视频成人 | 国产黄频在线观看高清免费 | 金牛网155755水心论坛黄大父母 | 天天做天天爱天天操 | 亚洲网站在线看 | 黑人巨大精品战中国美女 | 天天射寡妇射 | 午夜福到在线4国产 | 亚洲国产在线观看免费视频 | www久久| 精品久久99麻豆蜜桃666 | 国产精品午夜久久 | 亚洲精品视频在线 | 国产一页| 免费观看国产大片资源视频 | hezyo加勒比一区二区三区 | 国产卡一卡二卡3卡乱码免费 | 婷射吧| 沉香如屑西瓜视频免费观看完整版 | 好男人好资源在线观看 | 午夜dj影院在线视频观看完整 | 欧美午夜精品久久久久久黑人 | 亚洲视频一区在线播放 | 国产激情在线 | 亚洲国产精品网站久久 | 亚洲系列第一页 | 骚虎网站在线观看 | 羞羞答答影院在线 | 三级伦理在线播放 | 深夜日韩 | 高贵女王调奴vk | 亚洲精品久久久WWW游戏好玩 | 欧美在线播放成人免费 |