Java の基本 - データのシリアル化のためのシリアル化フレームワークの使用

なぜシリーズ化するのか?

現在、開発プロセス中に、対話する必要がある複数のプロセスと複数のサービス、または異なる言語のサービスが対話する必要があることがよくあります。このとき、データを送信するために固定プロトコルを使用することを選択するのが一般的ですが、多くの場合、 Java などの言語 JVM 言語では、送信されるデータは固有のクラス オブジェクトであり、そのクラス オブジェクトは現在の JVM 内でのみ有効であり、他の JVM や他の言語に渡す場合、クラス オブジェクトを直接識別することはできません。複数のサービスや異なる言語でやり取りする必要がある場合はどうすればよいでしょうか? このとき、固定のデータ形式を固定のプロトコルで送信する必要があり、このデータ送信プロトコルをシリアル化と呼び、データを送信する動作を定義したフレームワークコンポーネントをシリアル化コンポーネント(フレームワーク)とも呼びます。
シリアル化フレームワークには 2 つの操作が含まれます。1 つはオブジェクトまたはデータ構造を特定の形式 (転送データ プロトコル) に変換することであり、これをシリアル化と呼びます。もう 1 つは特定の形式をオブジェクトまたはデータ構造に変換するプロセスです。それをデシリアライズと呼びます。

連載の目的

  • データをネットワーク経由で送信したり、メモリやファイルに保存したりできるようにします。
  • データがアプリケーションから独立して存在できるようにします。

シリアル化の使用シナリオ

異なるサービス間の対話では、サービスは同じ言語でも異なる言語でも可能です。

Java言語の組み込みシリアル化

シリアル化の実装は、テキスト シリアル化、言語組み込みシリアル化、および言語間シリアル化に分けられますが、この記事では主に Java 言語組み込みシリアル化について説明します。
各言語には、基本的にシリアル化フレームワークが実装されています。このシリアル化方法は、言語組み込みシリアル化と呼ばれます。その利点は、言語がシリアル化フレームワーク (シリアル化プロトコル、シリアル化および逆シリアル化操作) を提供することです。使いやすいですが、欠点は、対話型アプリケーションであることです。同じ言語である必要があります。
以下では、Java の組み込みシリアル化フレームワークの使用について説明します。Java シリアル化プロトコルはバイト シーケンス (jvm によって実装) です。

シリアル化フレームワークで使用されるコア
  • シリアル化インターフェイス (シリアル化可能および外部化可能)

    シリアル化する必要があるクラス オブジェクトは、このインターフェイスを継承する必要があります。現在のインターフェイス変更によって定義されたクラス オブジェクトのみが、指定された方法でオブジェクトを送信できます。

  • シリアル化ID-シリアルバージョンUID

    バージョン不一致によるシリアル化失敗を防ぐため、送信・読み出しに使用する両端処理(javaBean)のバージョンが一致しているか確認してください。
    コンパイラーは、ID をシリアル化する 2 つの方法を提供します。1 つは、値 1L を持つデフォルトの versionID を生成する方法で、もう 1 つは、クラス名、インターフェース名、メンバーのメソッドおよび属性に基づいて 64 ビットのハッシュ フィールドを生成する方法です。など、クラス名、メソッド名、変数が変更されている場合、またはスペース、コメント、改行、その他の操作がある限り、計算されるハッシュ フィールドは異なります。もちろん、ここで注意する必要があります。 -上記の操作を行うたびに実行します。serialVerionUID を 1 回生成します (コンパイラは自動的に変更しません)。
    デフォルトの固定値 1L と 64 ビットのハッシュ値は自分で計算する必要はありません シリアル化インターフェイスを継承するクラスの場合、シリアル化 ID フィールドがない場合、クラス名の下に黄色の波線が表示されます。クラス名の上にマウスを置き、目的のメソッドを選択すると、シリアル化された ID フィールドが自動的に追加されます (変更がある場合は削除し、プロンプトに従って追加します)。

  • オブジェクトのシリアル化とデータ書き込み操作 (出力ストリーム java.io.ObjectOutputStream)

    シリアル化操作を実行し、シリアル化されたデータをファイルに書き込むか、送信するために使用されます。

  • データ読み取りおよびオブジェクトの逆シリアル化操作 (入力ストリーム java.io.ObjectInputStream)

    ネットワークから受信したファイルまたはデータをオブジェクトに逆シリアル化する逆シリアル化操作を実行するために使用されます。

ケース 1 - 基本的なシリアル化と逆シリアル化 シリアル化可能

以下では、ファイルに格納されているシリアル化されたオブジェクトを取り上げ、ファイルを読み取り、そのオブジェクトを例として使用してシリアル化フレームワークの使用法を説明します。この使用法は、データを送信する前にシリアル化することと同じです。これは両方に必要であるためです。データ送信とファイルアクセス 入力ストリームと出力ストリームのうち、入力ストリームと出力ストリームを取得するためのパラメータのみが不一致です。

人物クラスの実装
public class Person implements Serializable {
    
    
	//64位哈希序列化ID
	private static final long serialVersionUID = 8247451571741032209L;
	private String name;
	private int age;
	private transient boolean isMan; // true=男,false=女

	public Person(String name, int age, boolean isMan) {
    
    
		this.name = name;
		this.age = age;
		this.isMan = isMan;
	}

	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 boolean isMan() {
    
    
		return isMan;
	}

	public void setMan(boolean isMan) {
    
    
		this.isMan = isMan;
	}
	
	/*此方法只是用于打印,与序列化无关*/
    public String toString() {
    
    
        return "Person{" + "name=" + name  + ",age = " + age+",isMan = " + isMan + "}";
    }

}
シリアル化操作
public static void writeObject() {
    
    
		try {
    
    
			// 0. 创建一个ObjectOutputStream输出流
			ObjectOutputStream oos = new ObjectOutputStream(
					new FileOutputStream("E:/object.txt"));
			// 1. 将对象序列化到文件s
			Person person = new Person("lilu", 18, true);
			oos.writeObject(person);
			System.out.println("Person对象已写入object.txt文件");
		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
	}
逆シリアル化操作
public static void readObject() {
    
    
		try {
    
    
			// 0. 创建ObjectInputStream
			ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
					"E:/object.txt"));
			Person person1 = (Person) ois.readObject();
			System.out.println("读取到的Person对象数据如下:");
			System.out.println(person1);
		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
	}
メイン関数呼び出し
public static void main(String[] args) {
    
    
		writeObject();
		readObject();
	}
演算結果

ここに画像の説明を挿入します

Java シリアル化の使用法の概要
  • Java のシリアル化はオブジェクト属性 (オブジェクト クラス名、変数の型、変数データ) の転送のみを目的としており、メソッドはシリアル化のプロセスとは何の関係もありません。
  • クラス内の特定のメンバー変数はシリアル化する必要がないため、transient を使用してフィールドを宣言します。
  • クラスの静的変数 (static によって変更された変数) はシリアル化されません。
  • メンバーは参照シリアル化であり、この参照型に対応するクラスもシリアル化可能である必要があります。
  • シリアル化は推移的です。親クラスがシリアル化を実装すると、サブクラスはシリアル化インターフェイスを明示的に実装せずに自動的にシリアル化を実装します。次に、サブクラスはシリアル化を実装し、親クラスはシリアル化を実装しません。この場合、失敗します。同じオブジェクトを複数回シリアル化した場合、同じオブジェクトが複数回シリアル化されることはなく、何度シリアル化しても同じオブジェクトのみが得られます。

拡大する

  • カスタムシリアル化、writeObject と readObject をオーバーライドする
  • インターフェイスの継承外部化可能
  • シリアル化フレームワークのソースコードの詳細説明
  • クロス言語シリアル化の実装

参考リンク

Java 連載ならこの記事を読むだけ!
JAVAシリアル化の詳しい説明
初心者向けチュートリアル - Javaシリアル化

おすすめ

転載: blog.csdn.net/li1500742101/article/details/105509360