国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

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

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

服務器之家 - 編程語言 - Java教程 - Java對象的序列化與反序列化詳解

Java對象的序列化與反序列化詳解

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

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

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

對象轉換為字節序列的過程稱為對象的序列化,把字節序列恢復為對象的過程稱為對象的反序列化。
對象的序列化主要有兩種途徑:

Ⅰ . 把對象的字節序列永久地保存到硬盤上,通常存放在一個文件中
Ⅱ.  在網絡上傳送對象的字節序列。

當兩個進程在進行遠程通信時,彼此可以發送各種類型的數據。無論是何種類型的數據,都會以二進制序列的形式在網絡上傳送。發送方需要把這個Java對象轉換為字節序列,才能在網絡上傳送;接收方則需要把字節序列再恢復為Java對象。

二、序列化API

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

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

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

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

范例:對象序列化與反序列化

①. 定義一個Person類,實現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類對象

?
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對象
   *
   * @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對象
   *
   * @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("對象序列化成功!");
    out.close();
  }
}

運行如圖所示:

Java對象的序列化與反序列化詳解

三、serialVersionUID的作用

將對象序列化與反序列化范例中的serialVersionUID從Person類中去除,從新運行程序,結果會發現對象序列化成功、反序列化也成功了?,F在添加一個屬性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 + "]";
  }
}

然后執行反序列操作:

?
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對象
   *
   * @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;
  }
}

 運行發現,會出現如下錯誤:
Exception in thread "main" java.io.InvalidClassException: com.pegasus.serializable.Person; local class incompatible: stream classdesc serialVersionUID = 2521373692768252888, local class serialVersionUID = -6354757228515182324 

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

下面將Person類中指定serialVersionUID,重新執行序列化操作,將Person對象序列化到本地硬盤的Person.txt文件存儲,然后修改Person類,之后再次反序列化測試,將會發現程序就沒有異常了。

四、transient

當使用Serializable接口實現序列化操作時,如果一個對象中的某個屬性不希望被序列化的話,則可以使用transient關鍵字進行聲明。如下面的示例:

?
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();
  }
}

結果如下:

Java對象的序列化與反序列化詳解

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲精品久久久一区二区三区 | 午夜精品一区二区三区在线播放 | 日韩成人免费av | 亚洲国产欧美在线 | 欧美成人一区二区三区片免费 | 久久久久久亚洲 | 亚洲欧美日韩在线一区 | 日韩精品一级毛片 | 天堂av资源 | 日本一区二区免费视频 | www.操.com| 成人3d动漫一区二区三区91 | 日本一区二区三区四区 | 在线观看免费毛片视频 | 黄色影院在线观看 | 亚洲欧洲精品成人久久奇米网 | 日韩欧美在线一区二区 | 国产精品成人在线观看 | 久久久久综合视频 | 成人免费毛片aaaaaa片 | 亚洲视频精品 | 国产黄色精品 | 亚洲综合第一页 | 狠狠草视频 | 午夜视频免费在线观看 | 黄免费看 | 日日视频| 欧美日本韩国一区二区 | 91中文字幕在线 | 欧美精品在线看 | 这里只有精品在线 | 日韩精品一区二区三区四区五区 | 国产精品毛片一区二区 | 国产精品免费看 | 久久久免费 | 国产美女一区二区三区 | 亚洲一区欧美一区 | av大片在线观看 | 色吧综合网 | 成人免费高清 | 人人人人澡人人爽人人澡 |