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

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

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

服務(wù)器之家 - 編程語言 - Java教程 - Java對(duì)象的序列化與反序列化詳解

Java對(duì)象的序列化與反序列化詳解

2020-12-15 14:40珀伽 Java教程

這篇文章主要為大家詳細(xì)介紹了Java對(duì)象的序列化與反序列化的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

一、序列化反序列化的概念

對(duì)象轉(zhuǎn)換為字節(jié)序列的過程稱為對(duì)象的序列化,把字節(jié)序列恢復(fù)為對(duì)象的過程稱為對(duì)象的反序列化。
對(duì)象的序列化主要有兩種途徑:

Ⅰ . 把對(duì)象的字節(jié)序列永久地保存到硬盤上,通常存放在一個(gè)文件中
Ⅱ.  在網(wǎng)絡(luò)上傳送對(duì)象的字節(jié)序列。

當(dāng)兩個(gè)進(jìn)程在進(jìn)行遠(yuǎn)程通信時(shí),彼此可以發(fā)送各種類型的數(shù)據(jù)。無論是何種類型的數(shù)據(jù),都會(huì)以二進(jìn)制序列的形式在網(wǎng)絡(luò)上傳送。發(fā)送方需要把這個(gè)Java對(duì)象轉(zhuǎn)換為字節(jié)序列,才能在網(wǎng)絡(luò)上傳送;接收方則需要把字節(jié)序列再恢復(fù)為Java對(duì)象。

二、序列化API

1. 對(duì)象輸出流(ObjectOutputStream)的常用方法:

?
1
2
3
4
// 創(chuàng)建寫入指定 OutputStream 的 ObjectOutputStream。此構(gòu)造方法將序列化流部分寫入底層流
public ObjectOutputStream(OutputStream out) throws IOException
// 將指定的對(duì)象寫入 ObjectOutputStream
public final void writeObject(Object obj) throws IOException

2. 對(duì)象輸入流(ObjectInputStream)的常用方法:

?
1
2
3
4
// 創(chuàng)建從指定 InputStream 讀取的 ObjectInputStream。
public ObjectInputStream(InputStream in) throws IOException
// 從 ObjectInputStream 讀取對(duì)象。對(duì)象的類、類的簽名和類及所有其超類型的非瞬態(tài)和非靜態(tài)字段的值都將被讀取。
public final Object readObject() throws IOException, ClassNotFoundException

范例:對(duì)象序列化與反序列化

①. 定義一個(gè)Person類,實(shí)現(xiàn)Serializable接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Person implements Serializable {
  /**
   * 序列化ID
   */
  private static final long serialVersionUID = 3817849972563375707L;
  private String name;
  private int age;
  private String sex;
   
  public String getName() {return name;  }
  public void setName(String name) {this.name = name; }
  public int getAge() {return age;  }
  public void setAge(int age) {this.age = age;  }
  public String getSex() {return sex; }
  public void setSex(String sex) {this.sex = sex; }
}

 ②. 序列化和反序列化Person類對(duì)象

?
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
public class TestObjSerializeAndDeserialize {
  public static void main(String[] args) throws FileNotFoundException,
      IOException, ClassNotFoundException {
    serializePerson();
    Person person = deserializePerson();
    System.out.println(MessageFormat.format("name={0},age={1},sex={2}",
        person.getName(), person.getAge(), person.getSex()));
  }
 
  /**
   * 反序列化Person對(duì)象
   *
   * @throws IOException
   * @throws FileNotFoundException
   * @throws ClassNotFoundException
   */
  private static Person deserializePerson() throws FileNotFoundException,
      IOException, ClassNotFoundException {
    ObjectInputStream in = new ObjectInputStream(new FileInputStream(
        new File("E:\\person.txt")));
    Person person = (Person) in.readObject();
    System.out.println("反序列化成功!");
    return person;
  }
 
  /**
   * 序列化Person對(duì)象
   *
   * @throws IOException
   * @throws FileNotFoundException
   */
  private static void serializePerson() throws FileNotFoundException,
      IOException {
    Person person = new Person();
    person.setName("pegasus");
    person.setAge(24);
    person.setSex("男");
    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
        new File("E:\\person.txt")));
    out.writeObject(person);
    System.out.println("對(duì)象序列化成功!");
    out.close();
  }
}

運(yùn)行如圖所示:

Java對(duì)象的序列化與反序列化詳解

三、serialVersionUID的作用

將對(duì)象序列化與反序列化范例中的serialVersionUID從Person類中去除,從新運(yùn)行程序,結(jié)果會(huì)發(fā)現(xiàn)對(duì)象序列化成功、反序列化也成功了。現(xiàn)在添加一個(gè)屬性address,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Person implements Serializable {
  private String name;
  private int age;
  private String sex;
  private String address;
   
  public String getName() {return name;  }
  public void setName(String name) {this.name = name; }
  public int getAge() {return age;  }
  public void setAge(int age) {this.age = age;  }
  public String getSex() {return sex; }
  public void setSex(String sex) {this.sex = sex; }
  public String getAddress() {return address; }
  public void setAddress(String address) {this.address = address; }  
  @Override
  public String toString() {
    return "Person [name=" + name + ", age=" + age + ", sex=" + sex
        + ", address=" + address + "]";
  }
}

然后執(zhí)行反序列操作:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class DeserializePerson {
  public static void main(String[] args) throws FileNotFoundException, ClassNotFoundException, IOException {
    Person person = deserializePerson();
    System.out.println(person);
  }
 
  /**
   * 反序列化Person對(duì)象
   *
   * @throws IOException
   * @throws FileNotFoundException
   * @throws ClassNotFoundException
   */
  private static Person deserializePerson() throws FileNotFoundException,
      IOException, ClassNotFoundException {
    ObjectInputStream in = new ObjectInputStream(new FileInputStream(
        new File("E:\\person.txt")));
    Person person = (Person) in.readObject();
    System.out.println("反序列化成功!");
    return person;
  }
}

 運(yùn)行發(fā)現(xiàn),會(huì)出現(xiàn)如下錯(cuò)誤:
Exception in thread "main" java.io.InvalidClassException: com.pegasus.serializable.Person; local class incompatible: stream classdesc serialVersionUID = 2521373692768252888, local class serialVersionUID = -6354757228515182324 

意思是,文件流中的class和修改過后的class,不兼容了,處于安全機(jī)制考慮,程序拋出錯(cuò)誤,而且拒絕載入。如果我們真的需要在序列化后添加一個(gè)字段或者方法,應(yīng)該怎么辦?其實(shí)也很簡(jiǎn)單,只需自己去指定serialVersionUID即可。在上面的例子中,沒有給Person類指定serialVersionUID,那么java編譯器會(huì)自動(dòng)給這個(gè)class生成一個(gè)serialVersionUID,只要對(duì)這個(gè)文件添加一個(gè)空格,得到的UID都會(huì)不同,這個(gè)編號(hào)是唯一的。所以,添加一個(gè)字段后,由于沒有顯示指定serialVersionUID,編譯器又為我們生成一個(gè)UID,當(dāng)然和前面保存在文件中的哪一個(gè)不一樣,于是出現(xiàn)兩個(gè)版本號(hào)不一致的錯(cuò)誤。因此,只要自己指定serialVersionUID,就可在序列化以后,去添加一個(gè)字段,或者方法,而不會(huì)影響后期的反序列化,反序列后的對(duì)象還會(huì)多了方法和屬性。

下面將Person類中指定serialVersionUID,重新執(zhí)行序列化操作,將Person對(duì)象序列化到本地硬盤的Person.txt文件存儲(chǔ),然后修改Person類,之后再次反序列化測(cè)試,將會(huì)發(fā)現(xiàn)程序就沒有異常了。

四、transient

當(dāng)使用Serializable接口實(shí)現(xiàn)序列化操作時(shí),如果一個(gè)對(duì)象中的某個(gè)屬性不希望被序列化的話,則可以使用transient關(guān)鍵字進(jìn)行聲明。如下面的示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Customer implements Serializable{
  private static final long serialVersionUID = -4020382581484304699L;
  private String name; 
  private transient String address; // 此屬性不被序列化
 
  public Customer(String name, String address) {
    this.name = name;
    this.address = address;
  }
 
  @Override
  public String toString() {
    return "Customer [name=" + name + ", address=" + address + "]";
  }
}

序列化、反序列化Customer,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class TestCustomer {
  public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
    serializeCustomer();
    deserializeCustomer();
  }
 
  private static void deserializeCustomer() throws FileNotFoundException, IOException, ClassNotFoundException {
    ObjectInputStream in = new ObjectInputStream(new FileInputStream(
        new File("E:\\customer.txt")));
    Customer customer = (Customer) in.readObject();
    System.out.println(customer);
    in.close();
  }
 
  private static void serializeCustomer() throws FileNotFoundException, IOException {
    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
        new File("E:\\customer.txt")));
    out.writeObject(new Customer("pegasus", "甘肅"));
    System.out.println("序列化成功!");
    out.close();
  }
}

結(jié)果如下:

Java對(duì)象的序列化與反序列化詳解

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://blog.csdn.net/qq_25583079/article/details/48624425

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美不卡一区二区三区免 | 国产精品视频免费观看 | 毛片手机在线视频免费观看 | 亚洲天堂一区二区在线观看 | 特级一级全黄毛片免费 | 2018天天拍拍拍免费视频 | 婷婷久久热99在线精品 | 特黄aa级毛片免费视频播放 | 5x视频在线观看 | 国产亚洲一区二区三区 | 男女做受快插大片 | 欧美亚洲欧美 | 午夜无码国产理论在线 | 2020韩国r级理论片在线观看 | 12345国产精品高清在线 | 人人九九 | 好大好硬好长好爽a网站 | 性做久久久久久久久浪潮 | 日韩欧美一区二区三区中文精品 | 99久久精彩视频 | 国内精品国语自产拍在线观看55 | 免费xxxxx大片在线观看影视 | 女仆掀起蕾丝裙被打屁股作文 | 欧美xxxbrazzers| 国产成人精品视频午夜 | 国产yw193.㎝m在线观看 | 啪一啪日一日 | sex5·性屋娱乐 | 日本96在线精品视频免费观看 | 精品suv一区二区三区 | 亚洲一区二区精品推荐 | 我强进了老师身体在线观看 | 国产精品露脸国语对白手机视频 | 亚洲六月丁香六月婷婷蜜芽 | 免费看日本 | 国产精品色图 | 日产精品一二三四区国产 | 四虎www.| 国产一区在线播放 | 亚洲国产资源 | 99视频全部看免费观 |