激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(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 對象序列化 NIO NIO2詳細(xì)介紹及解析

Java 對象序列化 NIO NIO2詳細(xì)介紹及解析

2020-08-06 15:21lqh Java教程

這篇文章主要介紹了Java 對象序列化 NIO NIO2詳細(xì)介紹及解析的相關(guān)資料,序列化機(jī)制可以使對象可以脫離程序的運行而對立存在,需要的朋友可以參考下

Java 對象序列化 NIO NIO2詳細(xì)介紹及解析

概要:

對象序列化

對象序列化機(jī)制允許把內(nèi)存中的Java對象轉(zhuǎn)換成與平臺無關(guān)的二進(jìn)制流,從而可以保存到磁盤或者進(jìn)行網(wǎng)絡(luò)傳輸,其它程序獲得這個二進(jìn)制流后可以將其恢復(fù)成原來的Java對象。 序列化機(jī)制可以使對象可以脫離程序的運行而對立存在

序列化的含義和意義

序列化

序列化機(jī)制可以使對象可以脫離程序的運行而對立存在

序列化(Serialize)指將一個java對象寫入IO流中,與此對應(yīng)的是,對象的反序列化(Deserialize)則指從IO流中恢復(fù)該java對象

如果需要讓某個對象可以支持序列化機(jī)制,必須讓它的類是可序列化(serializable),為了讓某個類可序列化的,必須實現(xiàn)如下兩個接口之一:

  • Serializable:標(biāo)記接口,實現(xiàn)該接口無須實現(xiàn)任何方法,只是表明該類的實例是可序列化的
  • Externalizable

所有在網(wǎng)絡(luò)上傳輸?shù)膶ο蠖紤?yīng)該是可序列化的,否則將會出現(xiàn)異常;所有需要保存到磁盤里的對象的類都必須可序列化;程序創(chuàng)建的每個JavaBean類都實現(xiàn)Serializable;

使用對象流實現(xiàn)序列化

實現(xiàn)Serializable實現(xiàn)序列化的類,程序可以通過如下兩個步驟來序列化該對象:

1.創(chuàng)建一個ObjectOutputStream,這個輸出流是一個處理流,所以必須建立在其他節(jié)點流的基礎(chǔ)之上

?
1
2
// 創(chuàng)建個ObjectOutputStream輸出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"));

2.調(diào)用ObjectOutputStream對象的writeObject方法輸出可序列化對象

?
1
2
// 將一個Person對象輸出到輸出流中
oos.writeObject(per);

定義一個NbaPlayer類,實現(xiàn)Serializable接口,該接口標(biāo)識該類的對象是可序列化的

?
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
public class NbaPlayer implements java.io.Serializable
{
  private String name;
  private int number;
  // 注意此處沒有提供無參數(shù)的構(gòu)造器!
  public NbaPlayer(String name, int number)
  {
    System.out.println("有參數(shù)的構(gòu)造器");
    this.name = name;
    this.number = number;
  }
 
  // name的setter和getter方法
  public void setName(String name)
  {
    this.name = name;
  }
  public String getName()
  {
    return this.name;
  }
 
  // number的setter和getter方法
  public void setNumber(int number)
  {
    this.number = number;
  }
  public int getNumber()
  {
    return this.number;
  }
}

使用ObjectOutputStream將一個NbaPlayer對象寫入磁盤文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.io.*;
 
public class WriteObject
{
  public static void main(String[] args)
  {
    try(
      // 創(chuàng)建一個ObjectOutputStream輸出流
      ObjectOutputStream oos = new ObjectOutputStream(
        new FileOutputStream("object.txt")))
    {
      NbaPlayer player = new NbaPlayer("維斯布魯克", 0);
      // 將player對象寫入輸出流
      oos.writeObject(player);
    }
    catch (IOException ex)
    {
      ex.printStackTrace();
    }
  }
}

反序列化

從二進(jìn)制流中恢復(fù)Java對象,則需要使用反序列化,程序可以通過如下兩個步驟來序列化該對象:

1.創(chuàng)建一個ObjectInputStream輸入流,這個輸入流是一個處理流,所以必須建立在其他節(jié)點流的基礎(chǔ)之上

?
1
2
// 創(chuàng)建個ObjectInputStream輸出流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.txt"));

2.調(diào)用ObjectInputStream對象的readObject()方法讀取流中的對象,該方法返回一個Object類型的Java對象,可進(jìn)行強(qiáng)制類型轉(zhuǎn)換成其真實的類型

?
1
2
// 從輸入流中讀取一個Java對象,并將其強(qiáng)制類型轉(zhuǎn)換為Person類
Person p = (Person)ois.readObject();

從object.txt文件中讀取NbaPlayer對象的步驟

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.io.*;
public class ReadObject
{
  public static void main(String[] args)
  {
    try(
      // 創(chuàng)建一個ObjectInputStream輸入流
      ObjectInputStream ois = new ObjectInputStream(
        new FileInputStream("object.txt")))
    {
      // 從輸入流中讀取一個Java對象,并將其強(qiáng)制類型轉(zhuǎn)換為NbaPlayer類
      NbaPlayer player = (NbaPlayer)ois.readObject();
      System.out.println("名字為:" + player.getName()
        + "\n號碼為:" + player.getNumber());
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
  }
}

反序列化讀取的僅僅是Java對象的數(shù)據(jù),而不是Java類,因此采用反序列化恢復(fù)Java對象時,必須提供Java對象所屬的class文件,否則會引發(fā)ClassNotFoundException異常;反序列化機(jī)制無須通過構(gòu)造器來初始化Java對象

如果使用序列化機(jī)制向文件中寫入了多個Java對象,使用反序列化機(jī)制恢復(fù)對象必須按照實際寫入的順序讀取。當(dāng)一個可序列化類有多個父類時(包括直接父類和間接父類),這些父類要么有無參的構(gòu)造器,要么也是可序列化的—否則反序列化將拋出InvalidClassException異常。如果父類是不可序列化的,只是帶有無參數(shù)的構(gòu)造器,則該父類定義的Field值不會被序列化到二進(jìn)制流中

對象引用的序列化

如果某個類的Field類型不是基本類型或者String類型,而是另一個引用類型,那么這個引用類型必須是可序列化的,否則有用該類型的Field的類也是不可序列化的

?
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
public class AllStar implements java.io.Serializable
{
  private String name;
  private NbaPlayer player;
  public AllStar(String name, NbaPlayer player)
  {
    this.name = name;
    this.player = player;
  }
  // 此處省略了name和player的setter和getter方法
 
  // name的setter和getter方法
  public String getName()
  {
    return this.name;
  }
 
  public void setName(String name)
  {
    this.name = name;
  }
 
  // player的setter和getter方法
  public NbaPlayer getPlayer()
  {
    return player;
  }
 
  public void setPlayer(NbaPlayer player)
  {
    this.player = player;
  }
}

Java特殊的序列化算法

  • 所有保存到磁盤中的對象都有一個序列化編號
  • 當(dāng)程序試圖序列化一個對象時,程序?qū)⑾葯z查該對象是否已經(jīng)被序列化過,只有該對象從未(在本次虛擬中機(jī))被序列化過,系統(tǒng)才會將該對象轉(zhuǎn)換成字節(jié)序列并輸出
  • 如果某個對象已經(jīng)序列化過,程序?qū)⒅皇侵苯虞敵鲆粋€序列化編號,而不是再次重新序列化該對象
?
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
import java.io.*;
public class WriteAllStar
{
  public static void main(String[] args)
  {
    try(
      // 創(chuàng)建一個ObjectOutputStream輸出流
      ObjectOutputStream oos = new ObjectOutputStream(
        new FileOutputStream("allStar.txt")))
    {
      NbaPlayer player = new NbaPlayer("詹姆斯哈登", 13);
      AllStar allStar1 = new AllStar("西部全明星", player);
      AllStar allStar2 = new AllStar("首發(fā)后衛(wèi)", player);
      // 依次將四個對象寫入輸出流
      oos.writeObject(allStar1);
      oos.writeObject(allStar2);
      oos.writeObject(player);
      oos.writeObject(allStar2);
    }
    catch (IOException ex)
    {
      ex.printStackTrace();
    }
  }
}

4個寫入輸出流的對象,實際上只序列化了3個,而且序列的兩個AllStar對象的player引用實際是同一個NbaPlayer對象。以下程序讀取序列化文件中的對象

?
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
import java.io.*;
public class ReadAllStar
{
  public static void main(String[] args)
  {
    try(
      // 創(chuàng)建一個ObjectInputStream輸出流
      ObjectInputStream ois = new ObjectInputStream(
        new FileInputStream("allStar.txt")))
    {
      // 依次讀取ObjectInputStream輸入流中的四個對象
      AllStar star1 = (AllStar)ois.readObject();
      AllStar star2 = (AllStar)ois.readObject();
      NbaPlayer player = (NbaPlayer)ois.readObject();
      AllStar star3 = (AllStar)ois.readObject();
      // 輸出true
      System.out.println("star1的player引用和player是否相同:"
        + (star1.getPlayer() == player));
      // 輸出true
      System.out.println("star2的player引用和player是否相同:"
        + (star2.getPlayer() == player));
      // 輸出true
      System.out.println("star2和star3是否是同一個對象:"
        + (star2 == star3));
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
  }
}

如果多次序列化同一個可變Java對象時,只有第一次序列化時才會把該Java對象轉(zhuǎn)換成字節(jié)序列并輸出

當(dāng)使用Java序列化機(jī)制序列化可變對象時,只有第一次調(diào)用WriteObject()方法來輸出對象時才會將對象轉(zhuǎn)換成字節(jié)序列,并寫入到ObjectOutputStream;即使在后面程序中,該對象的實例變量發(fā)生了改變,再次調(diào)用WriteObject()方法輸出該對象時,改變后的實例變量也不會被輸出

?
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
import java.io.*;
 
public class SerializeMutable
{
  public static void main(String[] args)
  {
 
    try(
      // 創(chuàng)建一個ObjectOutputStream輸入流
      ObjectOutputStream oos = new ObjectOutputStream(
        new FileOutputStream("mutable.txt"));
      // 創(chuàng)建一個ObjectInputStream輸入流
      ObjectInputStream ois = new ObjectInputStream(
        new FileInputStream("mutable.txt")))
    {
      NbaPlayer player = new NbaPlayer("斯蒂芬?guī)炖?quot;, 30);
      // 系統(tǒng)會player對象轉(zhuǎn)換字節(jié)序列并輸出
      oos.writeObject(player);
      // 改變per對象的name實例變量
      player.setName("塞斯庫里");
      // 系統(tǒng)只是輸出序列化編號,所以改變后的name不會被序列化
      oos.writeObject(player);
      NbaPlayer player1 = (NbaPlayer)ois.readObject();  //①
      NbaPlayer player2 = (NbaPlayer)ois.readObject();  //②
      // 下面輸出true,即反序列化后player1等于player2
      System.out.println(player1 == player2);
      // 下面依然看到輸出"斯蒂芬?guī)炖?quot;,即改變后的實例變量沒有被序列化
      System.out.println(player2.getName());
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
  }
}

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

原文鏈接:http://www.codeceo.com/article/java-serialization-nio-nio2.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲视频精品在线 | 曰韩在线视频 | 在线免费观看欧美 | 国产午夜电影在线观看 | 凹凸成人精品亚洲精品密奴 | 99亚洲国产精品 | 91av在线免费视频 | 在线日韩av电影 | 国产精品免费av一区二区三区 | 伦一区二区三区中文字幕v亚洲 | 国产亚洲精品综合一区91555 | 成人永久免费视频 | 美女久久久久久久久 | 久久久久久久.comav | 亚洲国产精品一区 | 91成人免费网站 | 久久久日韩精品一区二区 | 精品国产一区二区三 | 毛片哪里看 | 成人偷拍片视频在线观看 | 黄色片一区二区 | 久久久成人精品视频 | 黄色网络免费看 | 在线观看国产日韩 | 99久久久国产精品免费观看 | 亚洲影视在线观看 | 成人免费观看49www在线观看 | av成人在线电影 | 港台三级在线观看 | 国产毛片毛片 | 欧美一级高清免费 | 久久2019中文字幕 | 91麻豆蜜桃一区二区三区 | 91网站免费在线观看 | 九草视频| 日韩黄色成人 | 依人九九宗合九九九 | wankzhd | 免费男女乱淫真视频 | 国产精品久久久久久久久久电影 | 国产精品视频一区二区噜噜 |