1. 程式人生 > >Java序列化-Serializable和ProtocolBuffers

Java序列化-Serializable和ProtocolBuffers

1.什麼是Java序列化以及Java序列化的作用

Java平臺允許我們在記憶體中建立可複用的Java物件,一般情況下只有當JVM處於執行時,這些物件才可能存在,所以這些物件的生命週期比 JVM的生命週期更短暫。但現實應用中可能要求JVM在停止執行之後能夠儲存(持久化)指定的物件,並在之後需要時可重新讀取被持久化的物件。Java物件序列化就能夠幫助我們實現該要求。但是需要注意,物件序列化static(代表狀態)以及transient(代表臨時資料)不能夠被序列化。
所謂序列化其實就是將程式中的資料通過特定方式儲存到本地中。然後把Java物件轉換為位元組序列的過程稱為物件的序列化。核心就是將資料分解成位元組流以便儲存在檔案中或者在網路中傳輸。就好比我們現在擁有一件體積很大的物品,然後把他儘可能地通過某種方法拆卸變成更小的零件寄出去給被人,別人再通過這種方法把它組裝起來變回原本的樣子,這一步也就是我們所說的反序列化,Java序列化的過程大概就是這樣。

2.什麼時候需要Java序列化

1.將記憶體中的資料儲存至資料庫或者磁碟檔案中。
2.使用套接字進行網路傳輸資料。
3.物件序列化可以實現分散式物件。使用RMI遠端方法呼叫傳輸資料。

3.Java序列化的基本使用

使用的比較都的就是物件實現Serializable序列化介面,這個介面的主要作用就是標識該物件可序列化,在傳輸物件時JRE會進行相應的封裝,這裡給出一個基本使用的例子。

需要序列化的物件需要先實現Serializable介面

Player.java
package com.serializable;

import java.io.Serializable;
import
java.util.List; /** * java序列化物件 * @author hzk * @date 2018/9/20 */ public class Player implements Serializable{ private static final long serialVersionUID = -1602899989398586421L; private Integer playerId; private String name; private Integer age; private List<Integer> skills;
public Player(Integer playerId, String name, Integer age,List<Integer> skills) { this.playerId = playerId; this.name = name; this.age = age; this.skills = skills; } public Integer getPlayerId() { return playerId; } public void setPlayerId(Integer playerId) { this.playerId = playerId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public List<Integer> getSkills() { return skills; } public void setSkills(List<Integer> skills) { this.skills = skills; } }

由於物件已經實現了序列化介面,這裡我們對他進行序列化和反序列化操作驗證

SerUtils .java
package com.serializable;

import com.google.protobuf.InvalidProtocolBufferException;
import com.proto.PlayerModule;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * java序列化轉換
 * @author hzk
 * @date 2018/9/20
 */
public class SerUtils {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        byte[] bytes = toBytes();
        toPlayer(bytes);
    }

    /**
     * 序列化
     * @return
     * @throws IOException
     */
    private static byte[] toBytes() throws IOException {
        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(10);
        Player player = new Player(10, "Peter", 18,integers);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        //寫入物件
        objectOutputStream.writeObject(player);

        //獲取位元組資料
        byte[] bytes = byteArrayOutputStream.toByteArray();
        System.out.println(Arrays.toString(bytes));
        return bytes;
    }

    /**
     * 反序列化
     * @param bs
     * @throws InvalidProtocolBufferException
     */
    private static void toPlayer(byte[] bs) throws IOException, ClassNotFoundException {
        ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bs));
        Player player = (Player) objectInputStream.readObject();
        System.out.println("PlayInfo:"+player.getPlayerId()+":"+player.getName()+":"+player.getAge()+":"+player.getSkills());
    }
}

執行結果:
[-84, -19, 0, 5, 115, 114, 0, 23, 99, 111, 109, 46, 115, 101, 114, 105, 97, 108, 105, 122, 97, 98, 108, 101, 46, 80, 108, 97, 121, 101, 114, -23, -63, 90, -13, -63, 107, 123, -53, 2, 0, 4, 76, 0, 3, 97, 103, 101, 116, 0, 19, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 73, 110, 116, 101, 103, 101, 114, 59, 76, 0, 4, 110, 97, 109, 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 76, 0, 8, 112, 108, 97, 121, 101, 114, 73, 100, 113, 0, 126, 0, 1, 76, 0, 6, 115, 107, 105, 108, 108, 115, 116, 0, 16, 76, 106, 97, 118, 97, 47, 117, 116, 105, 108, 47, 76, 105, 115, 116, 59, 120, 112, 115, 114, 0, 17, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 73, 110, 116, 101, 103, 101, 114, 18, -30, -96, -92, -9, -127, -121, 56, 2, 0, 1, 73, 0, 5, 118, 97, 108, 117, 101, 120, 114, 0, 16, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 78, 117, 109, 98, 101, 114, -122, -84, -107, 29, 11, -108, -32, -117, 2, 0, 0, 120, 112, 0, 0, 0, 18, 116, 0, 5, 80, 101, 116, 101, 114, 115, 113, 0, 126, 0, 5, 0, 0, 0, 10, 115, 114, 0, 19, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 65, 114, 114, 97, 121, 76, 105, 115, 116, 120, -127, -46, 29, -103, -57, 97, -99, 3, 0, 1, 73, 0, 4, 115, 105, 122, 101, 120, 112, 0, 0, 0, 1, 119, 4, 0, 0, 0, 1, 113, 0, 126, 0, 9, 120]
PlayInfo:10:Peter:18:[10]

4.Protocol Buffers

4.1 什麼是Protocol Buffers?

什麼是Google Protocol Buffers?網上比較官方的說法是這樣的:
Google Protocol Buffers( 簡稱 Protobuf) 是 Google 公司內部的混合語言資料標準,目前已經正在使用的有超過 48,162 種報文格式定義和超過 12,183 個 .proto 檔案。他們用於 RPC 系統和持續資料儲存系統。
Protocol Buffers 是一種輕便高效的結構化資料儲存格式,可以用於結構化資料序列化,或者說序列化。它很適合做資料儲存或 RPC 資料交換格式。可用於通訊協議、資料儲存等領域的語言無關、平臺無關、可擴充套件的序列化結構資料格式。目前提供了 C++、Java、Python 三種語言的 API。

其實官方的解釋已經能夠大體解釋清楚Protocol buffers是什麼,其實它就是一個靈活的、高效的、自動化的用於對結構化資料進行序列化的協議,與XML相比,Protocol buffers序列化後的碼流更小、速度更快、操作更簡單。我們只需要將要被序列化的資料結構定義一次(使用.proto檔案定義),便可以使用特別生成的原始碼(使用protobuf提供的生成工具)輕鬆的使用不同的資料流完成對這些結構資料的讀寫操作,即使你使用不同的語言(protobuf的跨語言支援特性)。你甚至可以更新你的資料結構的定義(就是更新.proto檔案內容)而不會破壞依賴“老”格式編譯出來的程式。

4.2 為什麼使用Protocol Buffers?

首先我們對比一下普通Java序列化和Protobuf序列化轉換位元組的區別

Java序列化 [-84, -19, 0, 5, 115, 114, 0, 15, 99, 111, 109, 46, 106, 97, 118, 97, 46, 80, 108, 97, 121, 101, 114, -73, 43, 28, 39, -119, -86, -125, -3, 2, 0, 4, 73, 0, 3, 97, 103, 101, 74, 0, 8, 112, 108, 97, 121, 101, 114, 73, 100, 76, 0, 4, 110, 97, 109, 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 76, 0, 6, 115, 107, 105, 108, 108, 115, 116, 0, 16, 76, 106, 97, 118, 97, 47, 117, 116, 105, 108, 47, 76, 105, 115, 116, 59, 120, 112, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 101, 116, 0, 5, 112, 101, 116, 101, 114, 115, 114, 0, 19, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 65, 114, 114, 97, 121, 76, 105, 115, 116, 120, -127, -46, 29, -103, -57, 97, -99, 3, 0, 1, 73, 0, 4, 115, 105, 122, 101, 120, 112, 0, 0, 0, 1, 119, 4, 0, 0, 0, 10, 115, 114, 0, 17, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 73, 110, 116, 101, 103, 101, 114, 18, -30, -96, -92, -9, -127, -121, 56, 2, 0, 1, 73, 0, 5, 118, 97, 108, 117, 101, 120, 114, 0, 16, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 78, 117, 109, 98, 101, 114, -122, -84, -107, 29, 11, -108, -32, -117, 2, 0, 0, 120, 112, 0, 0, 3, -23, 120]
ProtoBuf [8, 101, 16, 20, 26, 5, 112, 101, 116, 101, 114, 32, -23, 7]

從轉換位元組的對比上就能很明顯發現ProtoBuf的優點之一:資料轉換佔用空間小
其實ProtoBuf所做的事情在之前更多的是由XML完成,但是ProtoBuf的優點遠不止於此,下面幾點也是ProtoBuf的會逐漸成為更多開發者序列化資料選擇的關鍵
1.平臺無關,語言無關,可擴充套件;
2.提供了友好的動態庫,使用簡單;
3.解析速度快,比對應的XML快約20-100倍;
4.序列化資料非常簡潔、緊湊,與XML相比,其序列化之後的資料量約為1/3到1/10;
5.自動生成資料訪問類方便應用程式的使用;

4.3 Protocol Buffers的基本使用

在使用ProtoBuf之前首先我們需要知道我們要先編寫一個.proto檔案去指定我們所需要序列化的資料結構。下面在介紹如何使用時會舉出這裡我們用到的例子,關於ProtoBuf這種資料描述語言這裡推薦兩篇部落格介紹一些規範,可以給大家可以參考一下
Protobuf3語言指南
google protobuf資料型別

player.proto
option java_package = "com.proto";
option java_outer_classname = "PlayerModule";

message PBPlayer{
    required int64 playerId = 100;
    required int32 age = 10;
    required string name = 111;
    required int32 skills = 8;
}

message PBResource{
    required int64 gold = 8;
    required int32 energy = 100;
}

編寫好了.proto檔案後,我們要生成對應的程式碼要先從網上將protoc.exe下載下來,這裡我一併放在一個目錄下方便執行,為了方便生成編寫一個.bat指令碼
ProtoBuf原始碼
ProtoBuf程式

build.bat
protoc ./*.proto --java_out=./
pause

使用之前還需要匯入對應版本的Jar包

pom.xml
 <!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
 <dependency>
     <groupId>com.google.protobuf</groupId>
     <artifactId>protobuf-java</artifactId>
     <version>2.4.1</version>
 </dependency>

執行指令碼之後會發現當前目錄下自動生成了一個層級目錄,裡面生成了一個java檔案 PlayerModule.java

這裡一大串程式碼都是ProtoBuf根據我們自己編寫的.proto檔案自動生成的,這裡我們來簡單地使用達成和Java序列化一樣的效果

PBUtils.java
package com.proto;

import com.google.protobuf.InvalidProtocolBufferException;

import java.util.Arrays;

/**
 * protocol buffers 轉換
 * @author hzk
 * @date 2018/9/20
 */
public class PBUtils {

    public static void main(String[] args) throws InvalidProtocolBufferException {
        byte[] bytes = toBytes();
        toPlayer(bytes);
    }

    /**
     * 序列化
     * @return
     */
    private static byte[] toBytes(){
        //獲取PBPlayer構造器
        PlayerModule.PBPlayer.Builder builder = PlayerModule.PBPlayer.newBuilder();
        //設定資料
        builder.setName("hhh").setAge(10).setSkills(10).setPlayerId(1);
        //構造物件
        PlayerModule.PBPlayer player = builder.build();
        //序列化成位元組陣列
        //This is supposed to be overridden by subclasses. 需要maven引用和生成java檔案的版本相同
        byte[] bytes = player.toByteArray();
        System.out.println(Arrays.toString(bytes));
        return bytes;
    }

    /**
     * 反序列化
     * @param bs
     * @throws InvalidProtocolBufferException
     */
    private static void toPlayer(byte[] bs) throws InvalidProtocolBufferException {
        PlayerModule.PBPlayer player = PlayerModule.PBPlayer.parseFrom(bs);
        System.out.println("PlayInfo:"+player.getPlayerId()+":"+player.getName()+":"+player.getAge()+":"+player.getSkills());
    }
}
執行結果:
[64, 10, 80, 10, -96, 6, 1, -6, 6, 3, 104, 104, 104]
PlayInfo:1:hhh:10:10

簡單幾步就能利用protobuf序列化我們需要的資料物件,並且可以發現序列化和反序列化的效率都十分高

5.自定義序列化協議

根據不同的業務需求和不同的應用場景,我們可能需要採取不同的序列化方式,開發人員也會根據具體需要自定義所需序列化規則,這裡介紹幾種大家可能會接觸到的自定義協議規則

第一種用的是大端位元組序列,先寫高位再寫低位
大端 小端和網路位元組序說明

Test1.java
package com.customSerializable.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;

/**
 * @author hzk
 * @date 2018/9/25
 */
public class Test1 {
    
    public static void main(String[] args) throws IOException {
        int id = 111; // 0110 1111
        int age = 23; //0001 0111

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] idBytes = int2byte(id);
        byte[] ageBytes = int2byte(age);
        System.out.println("Bytes id:"+ Arrays.toString(idBytes));
        System.out.println("Bytes age:"+ Arrays.toString(ageBytes));
        byteArrayOutputStream.write(idBytes);
        byteArrayOutputStream.write(ageBytes);
        byte[] outBytes = byteArrayOutputStream.toByteArray();

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(outBytes);
        byte[] idBytesIn = new byte[4];
        byteArrayInputStream.read(idBytesIn);
        System.out.println("Read Bytes id:"+Arrays.toString(idBytesIn));
        System.out.println("Read Bytes Trans id:"+byte2int(idBytesIn));

        byte[] ageBytesIn = new byte[4];
        byteArrayInputStream.read(ageBytesIn);
        System.out.println("Read Bytes age:"+Arrays.toString(ageBytesIn));
        System.out.println("Read Bytes Trans age:"+byte2int(ageBytesIn));

    }

    /**
     * 大端位元組序列(先寫高位,再寫低位)
     * @param i
     * @return
     */
    private static byte[] int2byte(int i){
        byte[] bytes = new byte[4];
        bytes[0] = (byte)(i >> 3*8);
        bytes[1] = (byte)(i >> 2*8);
        bytes[2] = (byte)(i >> 1*8);
        bytes[3] = (byte)(i >> 0*8);
        return bytes;
    }

    /**
     * 大端位元組反序列
     * @param bytes
     * @return
     */
    private static int byte2int(byte[] bytes){
        return (bytes[0] << 3*8)|(bytes[1] << 2*8)|(bytes[2] << 1*8)|(bytes[3] << 0*8);
    }

}
執行結果:
Bytes id:[0, 0, 0, 111]
Bytes age:[0, 0, 0, 23]
Read Bytes id:[0, 0, 0, 111]
Read Bytes Trans id:111
Read Bytes age:[0, 0, 0, 23]
Read Bytes Trans age:23

第二種用到了NIO中提供的ByteBuffer,相比上面的方法更加方便就能分解成位元組資料,但是缺點是需要指定要轉換資料的位元組大小

Test2.java
package com.customSerializable.test;

import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * ByteBuffer 需要指定大小
 * @author hzk
 * @date 2018/9/26
 */
public class Test2 {
    
    public static void main(String[] args){
        int id = 111;
        int age = 23;

        ByteBuffer buffer = ByteBuffer.allocate(8);
        buffer.putInt(id);
        buffer.putInt(age);
        byte[] array = buffer.array();
        System.out.println(Arrays.toString(array));

        ByteBuffer wrap = ByteBuffer.wrap(array);
        System.out.println(wrap.getInt());
        System.out.println(wrap.getInt());
    }
}

執行結果:
[0, 0, 0, 111, 0, 0, 0, 23]
111
23

第三種藉助了Netty提供的ChannelBuffers,可以利用該物件動態生成緩衝位元組資料的ChannelBuffer

pom.xml
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty</artifactId>
    <version>3.10.5.Final</version>
</dependency>
Test3.java
package com.customSerializable.test;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;

import java.util.Arrays;

/**
 * ChannelBuffers Netty工具
 * @author hzk
 * @date 2018/9/26
 */
public class Test3 {
    
    public static void main(String[] args){
        ChannelBuffer channelBuffer = ChannelBuffers.dynamicBuffer();
        channelBuffer.writeInt(111);
        channelBuffer.writeDouble(23.5);

        byte[] bytes = new byte[channelBuffer.writerIndex()];
        channelBuffer.readBytes(bytes);
        System.out.println(Arrays.toString(bytes));

        ChannelBuffer channelBuffer1 = ChannelBuffers.wrappedBuffer(bytes);
        System.out.println(channelBuffer1.readInt());
        System.out.println(channelBuffer1.readDouble());
    }
}
執行結果:
[0, 0, 0, 111, 64, 55, -128, 0, 0, 0, 0, 0]
111
23.5

第四種利用Netty提供的ChannelBuffers根據自定義的規則(例如序列化String字串型別資料時,首先寫入一個short型別資料表示該字串轉換為位元組陣列的長度,再寫入具體的位元組資料,集合亦是如此)封裝一個自定義序列化抽象類以供需要序列化的資料繼承使用

BufferFactory.java
package com.customSerializable.core;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;

import java.nio.ByteOrder;

/**
 * ChannelBuffers工具類
 * @author hzk
 * @date 2018/9/26
 */
public class BufferFactory{

    public static ByteOrder BYTE_ORDER = ByteOrder.BIG_ENDIAN;

    /**
     * 獲取一個ChannelBuffer
     * @return
     */
    public static ChannelBuffer getBuffer(){
        ChannelBuffer channelBuffer = ChannelBuffers.dynamicBuffer();
        return channelBuffer;
    }

    /**
     * 獲取一個ChannelBuffer 並寫入資料
     * @param bytes
     * @return
     */
    public static ChannelBuffer getBuffer(
            
           

相關推薦

Java序列-SerializableProtocolBuffers

1.什麼是Java序列化以及Java序列化的作用 Java平臺允許我們在記憶體中建立可複用的Java物件,一般情況下只有當JVM處於執行時,這些物件才可能存在,所以這些物件的生命週期比 JVM的生命週期更短暫。但現實應用中可能要求JVM在停止執行之後能夠儲存(

Java序列SerializableExternalizable

持久化對象 clu version catch 例程 對象 uri put one 紙上得來終覺淺,絕知此事要躬行 --陸遊 問渠那得清如許,為有源頭活水來 --朱熹 什麽是Java序列化?為什麽出現Java序列化?如何實現Java序列化? 一、

(雜記)Java序列Serializable序列

1.什麼是java序列化? 把物件轉化為位元組序列的過程稱為序列化 把位元組序列轉化為物件的過程稱為反序列化。 2.為什麼需要序列化? 序列化主要有兩個應用場景: 用於把物件從記憶體中儲存到磁碟中。 用於網路上傳輸物件 此處舉例解釋一下:比如Web開發中經常遇

java中的序列(Serializable)序列

由於JDK提供的這種預設的序列化機制是簡單的將物件變成位元組流, 有時候並不滿足我們的要求, 比如考慮到加密, 或者在反序列化完了後需要呼叫某個方法來初始化transient的屬性等等, JDK提供了一種擴充套件的方法來增加對序列化和反序列化的控制. 那就是可以讓序列化的物件實現下面兩個固定的方法(注意修

Java 序列Serializable詳解

Java 序列化技術可以使你將一個物件的狀態寫入一個Byte 流裡,並且可以從其它地方把該Byte 流裡的資料讀出來,重新構造一個相同的物件。這種機制允許你將物件通過網路進行傳播,並可以隨時把物件持久化到資料庫、檔案等系統裡。Java的序列化機制是RMI、EJB、RPC遠端呼叫等技術的

java序列機制Serialize介面

java序列化機制 Serialize 介面 java本身的序列化機制存在問題: 1.序列化資料結果比較大,傳輸效率低 2.不能跨語言對接 XML編碼格式的物件序列化機制成為主流 序列化機制: MessagePack Protocol Buffers Du

Java序列——Serializable、Externalizable原始碼閱讀與總結

序列化(Serialization):是將物件的狀態資訊轉換為可以儲存或傳輸的形式的過程。更通俗地講,是將該物件欄位和狀態資訊以位元組流的方式輸出到目的地。 一是實現pojo物件的讀寫操作,將每個物件轉換為位元組流,而這些位元組流可以被持久化到裝置上,再次讀取時會將位元組流

序列(SerializableParcelable介面)詳解

1.什麼是序列化? 就是一種處理物件流的機制。所謂物件流就是將物件的內容進行流化,我們可以對流化後的物件進行讀寫操作。也可以將流化後的物件傳輸於網路之間。 2.序列化的實現: 將需要被序列化的類實現Serializalbe,該介面沒有需要實現的方案,只是為了標識該

Java序列機制原理

本文講解了Java序列化的機制和原理。從文中你可以瞭解如何序列化一個物件,什麼時候需要序列化以及Java序列化的演算法。 有關Java物件的序列化和反序列化也算是Java基礎的一部分,下面對Java序列化的機制和原理進行一些介紹。 Java序列化演算法透析   Seri

android 支援的序列-------SerializableParcelble

android 支援兩種序列化:Serializable和Parcelble。前者是Java語言自帶的序列化機制,通過讀寫檔案實現物件的序列化和反序列化;後者是Android Os實現的序列化,它是通過讀寫記憶體來實現序列化,從而實現物件的傳遞。下面,就這兩種方式詳細說明。 Serializable S

JAVA 序列 序列 (Externalizable Serializable) 那些事

序列化控制 當我們對序列化進行控制時,可能某個特定子物件不想讓Java序列化機制自動儲存與恢復。如果子物件表示的是我們不希望將其序列化的敏感資訊(如密碼),通常會面臨這種情況。即使物件中的這些資訊

Java序列接口Serializable接口的作用總結

生命周期 read 避免 什麽 打開 序列號 依賴 為什麽 main 轉載 http://www.cnblogs.com/DreamDrive/p/4005966.html 一個對象有對應的一些屬性,把這個對象保存在硬盤上的過程叫做”持久化”. 把堆內存中的對象的生命周期延

java android 序列serializableparcelable

exceptio 對象的引用 undle ktr 實現原理 輸出 fin 使用 讀者 why 為什麽要了解序列化?—— 進行Android開發的時候,無法將對象的引用傳給Activities或者Fragments,我們需要將這些對象放到一個Intent或者Bundle裏面,

JAVA 對象序列——Serializable

對象狀態 java 打印 end alt 包含 系統 eth 顯式 1、序列化是幹什麽的? 簡單說就是為了保存在內存中的各種對象的狀態(也就是實例變量,不是方法),並且可以把保存的對象狀態再讀出來。雖然你可以用你自己的各種各樣的方法來保存object state

2018-07-25期 Java序列序列編程小案例

測試 product set pri get sof serial span not package cn.sjq.Serializable.java;import java.io.FileInputStream;import java.io.FileOutputStrea

JAVA序列序列

1、什麼是序列化和反序列化 序列化:物件序列化的最主要的用處就是在傳遞和儲存物件的時候,保證物件的完整性和可傳遞性。序列化是把物件轉換成有序位元組流,以便在網路上傳輸或者儲存在本地檔案中。序列化後的位元組流儲存了Java物件的狀態以及相關的描述資訊。序列化機制的核心作用就是物件狀態的儲存與重建。

java序列序列物件

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; impo

Think In Java——序列序列

1)Java中的Serializable介面和Externalizable介面有什麼區別? 這個是面試中關於Java序列化問的最多的問題。我的回答是,Externalizable介面提供了兩個方法writeExternal()和readExternal()。這兩個方法給我們

java 物件實現序列 Serializable()介面

總結一下Serializable介面的實現原理。 當一個類實現了Seializable介面(該介面僅為標記介面,不包含任何方法定義),表示該類可以序列化,序列化的目的是將一個實現了Serializable介面的物件可以轉換成一個位元組序列,儲存物件的狀態。 把該位元組序列

Java序列的方式、object類中的方法、介面抽象類的區別、ArrayList在迴圈過程中刪除

Java序列化的方式 a.是相應的物件實現了序列化介面Serializable,這個使用的比較多,對於序列化介面Serializable介面是一個空的介面,它的主要作用就是標識這個物件時可序列化的,jre物件在傳輸物件的時候會進行相關的封裝。 b.Externlizab