Java のシリアル化と逆シリアル化

高洛峰
リリース: 2016-10-29 10:56:57
オリジナル
1610 人が閲覧しました

1. シリアル化とは何ですか?なぜシリーズ化するのか?

Javaのシリアル化はオブジェクトをバイト列に変換するプロセスを指しますが、逆シリアル化はバイト列のみをターゲットオブジェクトに変換するプロセスです。

ブラウザにアクセスするときに、目にするテキスト、画像、音声、ビデオなどがバイナリシーケンスを通じて送信されることは誰もが知っています。では、Java オブジェクトを送信する必要がある場合、オブジェクトを最初にシリアル化することも可能でしょうか。 ?答えは「はい」です。まず Java オブジェクトをシリアル化して、それがネットワークと IO を介して送信され、宛先に到達したら逆シリアル化して必要なオブジェクトを取得し、最後に通信を完了する必要があります。

2. シリアル化の実装方法

2.1. JDK のキークラス ObjectOutputStream と ObjectInputStream を使用します

ObjectOutputStream クラスで、writeObject(Object object) メソッドを使用してオブジェクトをバイナリ形式で書き込みます。

ObjectInputStreamクラス内: readObject()メソッドを使用することで、バイナリストリームが入力ストリームから読み取られ、オブジェクトに変換されます。

2.2. ターゲットオブジェクトは最初に Serializable インターフェースを実装する必要があります

Student クラスを作成します:

public class Student implements Serializable {
    private static final long serialVersionUID = 3404072173323892464L;
    private String name;
    private transient String id;
    private String age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id='" + id + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public Student(String name, String id) {
        System.out.println("args Constructor");
        this.name = name;
        this.id = id;
    }

    public Student() {
        System.out.println("none-arg Constructor");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

}
ログイン後にコピー

コード全体を通して、Student クラスは Serializable インターフェイスを実装し、バージョンを生成します番号:

private static final long serialVersionUID = 3404072173323892464L;
ログイン後にコピー

] 最初:

1. Serializable インターフェイスの機能は、クラスをシリアル化する必要があることを識別することだけであり、Serializable インターフェイスはメソッドを提供しません。

2.serialVersionUid シリアル化バージョン番号は、作成するクラスのバージョンを区別し、逆シリアル化中にクラスのバージョンが一致しているかどうかを判断するために使用されます。矛盾している場合は、バージョン不一致例外が発生します。

3. transient キーワードは主にシリアル化したくない変数を無視するために使用されます

2.3. オブジェクトをシリアル化または逆シリアル化する

2.3.1 最初の書き込みメソッド:

public static  void main(String[] args){
        File file = new File("D:/test.txt");
        Student student = new Student("孙悟空","12");
        try {
            ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
            outputStream.writeObject(student);
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
            Student s = (Student) objectInputStream.readObject();
            System.out.println(s.toString());
            System.out.println(s.equals(student));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
ログイン後にコピー

オブジェクト Student を作成します次に、ObjectOutputStream クラスの writeObject() メソッドを通じてオブジェクトをファイルに出力します。

その後、ObjectinputStreamクラスのreadObject()メソッドでデシリアライズしてオブジェクトを取得します。

2.3.2 2 番目の書き込みメソッド:

Student クラスに writeObject() メソッドと readObject() メソッドを実装します:

private void writeObject(ObjectOutputStream objectOutputStream) throws IOException {
        objectOutputStream.defaultWriteObject();
        objectOutputStream.writeUTF(id);

    }

    private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
        objectInputStream.defaultReadObject();
        id = objectInputStream.readUTF();
    }
ログイン後にコピー

このシリアル化メソッドを通じて、実行したいシリアル化をカスタマイズできます。入力ストリームと出力ストリームはライン インスタンスに渡され、シリアル化および逆シリアル化されます。

2.3.3 3番目の記述方法:

Studentは、Externalnalizableインターフェースを実装しますが、Serializableインターフェースは実装しません

ExternaliableインターフェースはSerializableのサブクラスであり、Serializableインターフェースと同じ機能を持ちます:

public class Student implements Externalizable {
    private static final long serialVersionUID = 3404072173323892464L;
    private String name;
    private transient String id;
    private String age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id='" + id + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public Student(String name, String id) {
        System.out.println("args Constructor");
        this.name = name;
        this.id = id;
    }

    public Student() {
        System.out.println("none-arg Constructor");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }


    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(name);
        out.writeObject(id);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = (String) in.readObject();
        id = (String) in .readObject();
    }

}
ログイン後にコピー

Through前 2 番目の書き込みメソッドを比較すると、それらの実装原理は非常に似ていることがわかりますが、 Externalnalizable インターフェイスの実装では、最初のシリアル化メソッドはサポートされていません。このメソッドは、インターフェイス内で writeExternal() と readExternal() メソッドを実装するだけです。オブジェクトの。

3. インタビューでのシリアル化に関する質問:

1. シリアル化とは何か、およびシリアル化の実装方法

Java におけるオブジェクトのシリアル化はオブジェクトをバイナリ シーケンスに変換することであり、逆シリアル化はバイナリを変換することですオブジェクトへのシーケンスJava

1にシリアル化を実装する多くの方法があります。まず、2つのIOクラスObjectInputStreamとObjectOutputStreamを使用する必要があります。 ObjectOutputStream クラスと ObjectInputStream クラスの writeObject() メソッドと readObject() メソッドについて

2.2 シリアル化されたオブジェクトに writeObject() メソッドと readObject() メソッドを実装することで、ObjectOutputStream オブジェクトと ObjectInputStream オブジェクトを渡してシリアル化を完了します

3.外部化可能なインターフェースを実装します:

オブジェクトの直列化は、インターフェイスに writeExternal() メソッドと readExternal() メソッドを実装することによってのみ実現できます


2. 一時的なキーワード? transient修飾子で変更された変数をシリアル化するにはどうすればよいですか?
transient の機能は、シリアル化したくない変数をシールドすることです。オブジェクトは、シリアル化および逆シリアル化のプロセス中に変数を無視します。
上記のシリアル化メソッドで writeObject メソッドと readObject メソッドを実装し、メソッド内で出力ストリームまたは入力ストリームの writeUTF() メソッドと readUTF() メソッドを呼び出すことができます。
あるいは、Externalizable インターフェースを実装して、writeInitial() メソッドと readExternal() メソッドを実装してから、シーケンス オブジェクトをカスタマイズします。

3. シリアル化と逆シリアル化後のオブジェクトの一貫性を確保するにはどうすればよいですか? (異論があれば修正してください)
この問題についていくつかの情報を調べた結果、シリアル化と逆シリアル化のプロセス中に最初にオブジェクトを作成するため、シリアル化と逆シリアル化後のオブジェクトが一貫しているという保証はないことがわかりました。

したがって、データとバージョンが一貫していることだけを保証できますが、オブジェクトが一貫していることは保証できません。


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!