Javaのシリアライズとデシリアライズ概念

コーミングJavaのシリアル化の問題は、インターネット上で良い記事を見つけたときに今日、以下は、オリジナルのブログの内容は次のとおりです。

 

このインタフェース遭遇したJavaのシリアライズシリアライズは、我々は次のような質問を持っていることが
、どのようなシリアライズとデシリアライズの
B、役割。なぜ、このあなたはシリアル化したい理由ですSerializableインタフェース、達成するために
C、serialVersionUIDの値は、最後に、これは使用何、設定方法です。1L、数字のいくつかの長い文字列の一部、INGの混乱。
上記の問題の多くがあった場合、私はちょうどこのキーワードSerializableのを見ました。

この問題に対処するには、最初に、より重要なの質問を知っている必要があります。
すべてのJavaのIO内部でSerializableインタフェース、および関連するもの、。

1、シリアライズとデシリアライズ概念

シリアル化:プロセス・オブジェクトと呼ばれるオブジェクトのシーケンスを変換するには、バイトのシーケンスです。
デシリアライズ:バイトシーケンスデシリアライズされたオブジェクトを復元すると、オブジェクトと呼ばれています。

上記の説明は、プロ、ポイントに今人気の説明です。コードが実行されている場合、我々は、オブジェクトの多くを見ることができます(debug'veすべてがそれを作った)、
一つでも、それはオブジェクトのクラスのコレクション、多くのオブジェクトデータ、これらのデータ、することができ
、我々は彼を欲しい情報の一部シリアライズそして、永続的な保存されました。
これは説明のバイトの一連の処理に変身するために、これらのオブジェクトのメモリにあります。
これは、一般的なファイルになることです
、私は何ああ、どのような影響シリアル化するために、ファイルを保存することはできませんか?それは私が尋ねたものです。

2、どのような下の状況はシリアライズする必要があります

ときあなたは、メモリまたはデータベースファイルの時間を節約したいオブジェクトの状態、
ネットワーク上のソケット転送オブジェクトを使用したい、
あなたはRMI経由トランスポート・オブジェクトにしたい。
(正直、上記いくつか、私は預金のデータベースを使用している場合があります)

シリアライズする方法3、

Serializableインタフェースを実現するために
これらの理論上は、比較的単純なエンドでの実際のコードのシリアライズで次の外観はやってすることができ、およびバグの問題が生じています。
最初のオブジェクトコード、.javaファイルフライングピッグ

package com.lxk.model;
 
import java.io.Serializable;
 
/**
 * @author lxk on 2017/11/1
 */
public class FlyPig implements Serializable {
    //private static final long serialVersionUID = 1L;
    private static String AGE = "269";
    private String name;
    private String color;
    transient private String car;
 
    //private String addTip;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getColor() {
        return color;
    }
 
    public void setColor(String color) {
        this.color = color;
    }
 
    public String getCar() {
        return car;
    }
 
    public void setCar(String car) {
        this.car = car;
    }
 
    //public String getAddTip() {
    //    return addTip;
    //}
    //
    //public void setAddTip(String addTip) {
    //    this.addTip = addTip;
    //}
 
    @Override
    public String toString() {
        return "FlyPig{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", car='" + car + '\'' +
                ", AGE='" + AGE + '\'' +
                //", addTip='" + addTip + '\'' +
                '}';
    }

メモは、コメントコードがしばらくあることが様々な状況下で使用されます。
ここでの主な方法のことです

package com.lxk.test;
 
import com.lxk.model.FlyPig;
 
import java.io.*;
 
/**
 * 序列化测试
 *
 * @author lxk on 2017/11/1
 */
public class SerializableTest {
    public static void main(String[] args) throws Exception {
        serializeFlyPig();
        FlyPig flyPig = deserializeFlyPig();
        System.out.println(flyPig.toString());
 
    }
 
    /**
     * 序列化
     */
    private static void serializeFlyPig() throws IOException {
        FlyPig flyPig = new FlyPig();
        flyPig.setColor("black");
        flyPig.setName("naruto");
        flyPig.setCar("0000");
        // ObjectOutputStream 对象输出流,将 flyPig 对象存储到E盘的 flyPig.txt 文件中,完成对 flyPig 对象的序列化操作
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("d:/flyPig.txt")));
        oos.writeObject(flyPig);
        System.out.println("FlyPig 对象序列化成功!");
        oos.close();
    }
 
    /**
     * 反序列化
     */
    private static FlyPig deserializeFlyPig() throws Exception {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("d:/flyPig.txt")));
        FlyPig person = (FlyPig) ois.readObject();
        System.out.println("FlyPig 对象反序列化成功!");
        return person;
    }
}

2つのファイルストリーム動作説明上記の単純なクラス
出力ストリームを表すObjectOutputStreamのオブジェクト:
それのwriteObject(オブジェクトobj)メソッドは、ターゲット出力ストリームに書き込まれたバイトのオブジェクトOBJパラメーターが指定され、得られた配列をシリアル化することができますインチ
入力ストリームを表現するObjectInputStreamオブジェクト:
それのreadObject()メソッドは、それを入力ストリームソースからバイト列を読み出し、それらオブジェクトをデシリアライズし、リターンします。

どのように特定の動作条件をご覧ください。

最初:これらのコードまで、固定、ダイレクトRUN、効果を確認します。

実用的な結果は、彼はDになります:/flyPig.txtファイルを生成しました。

ビューの業績の観点から:
1、彼はシリアル化し、オブジェクトのデシリアライズを実現しました。
2は、過渡変更されたプロパティは、シリアライズされません。アウディの車、私はそれを見ていないし4周は、nullになりました。私の神。
3は、あなたが最初にこの静的変数AGEも友人に連載されていることを心配しないでください。これは、別のテストでした。

第二:この静的プロパティを検証するためには、次のように動作することができる、直列化および非直列化することができます。

 public static void main(String[] args) throws Exception {
        serializeFlyPig();
        //FlyPig flyPig = deserializeFlyPig();
        //System.out.println(flyPig.toString());
    }  

これは言うことを意味し、終わったら、最初の直列化は、ファイルへのオブジェクト。このオブジェクトは、静的変数と静的なものです。
今、それを変更するにはAGE flyPigクラス内の、26の値を変更します。
次に、コードを実行すると、図の実行結果の内側に見えます。

それを読んでいない、269のちょうどシーケンスを見ることができます。可能な場合でも、ちょうど26の変更は、これは、カバー26、269匹の魚でなければなりません。
だから、彼はシリアライズされません、この静的静的プロパティ、結論します。

第三:serialVersionUIDののデモンストレーションと使用の役割

最も暴力的な変化、直接モデルは、このインターフェイスクラスが実装を削除します。次いで、後者の方法のシリアライゼーションおよびデシリアライゼーションを行います。直接のエラー。
例外:持つNotSerializableExceptionを

それを行うことが推奨されていない、あまりにも暴力的です。

それはまた同様であり、上述した動作は、単独で、最初の実行のシリアル化方法。生成されたファイル。
その後、現象の抗シリアライズメソッドの実装は再び、見た後、プロパティaddTipを開きます。

 

例外:によりInvalidClassExceptionを以下に説明。
InvalidClassExceptionは:com.lxk.model.FlyPig、
ローカルクラス互換性:
ストリームclassdescのserialVersionUID = -3,983,502,914,954,951,240、
ローカルクラスのserialVersionUID = 7565838717623951575

説明:
私はこの割り当てのための明示的なserialVersionUIDのがないモデルですので、しかし、Javaは自動的に私の割り当てを与えるだろう、
このモデルに関連付けられた属性の値が算出されます。
私は、これはそれではない、まだaddTip属性だった、私はシリアル化するときであること、時間を保存し、
そのため、自動的に生成されたserialVersionUIDの値
彼は、私がこの値が異なっているJavaの自動生成されたのserialVersionUIDをデシリアライズ時にそれが例外をスローします。
(また、その後、シリアル化するためにIDと、デシリアライゼーションへのIDをオンにすることはできません。同じ問題です。)

ここでも、それは長いのserialVersionUID = 1L最終プライベート静的には、最初にシリアライズこの時間であり、コードのコメントこの行がオープン。addTip出し性最初のコメントそれ
シリアライズした後、このプロパティを開いているが、その後、デシリアライズさ。そして、何が起こるかを参照してください。

この時、コードが実行されるOKは、すべてが正常です。良いです。

私たちにこの現象の意義は何ですか。

すべての最初の古い鉄、この広い意味、あなたはシリアル化がやっているかわからない場合は、と彼は本当にメモリデータベースの友人の初め、ソケットトランスポートを、RMI輸送それとしてそれについて話されている場合。これがやっているかどうかは分かりませんが。あなたはバグが右のそれを揚げていない古いデータを、認識していない発生する可能性がありますときに、後で拡張し、このserialVersionUIDのを書いていない、モデル豆の実装にこのインタフェースを与えます。リコール上記のエラー条件という。すべての恐ろしい、誰がこの鍋の裏を考えてみて?

だから、そのような説があり、Serializableインタフェースを実装するとき、serialVersionUIDのは、この割り当てを与えなければならない、であることは、このような問題であるが、。
私達はちょうど実装、このインタフェースをコーディングを開始するとき、これはまた、説明した後、なぜEclipseのエディタ黄色の警告には、このIDの値を追加する必要があります。そして、あなたはまだ数字の長いリストを来るのか分かりません。

以下はOK、それを設定する方法を最後にserialVersionUIDの値を説明しています。

まずので、自分の手を持っている、あなたはJavaがあなたに割り当てを与える、独自の割り当てを行くことができないが、これは、バグの上に非常に安全になります。
だから、どのように私は、Eclipseは自動的に数字の長い文字列にあなたを割り当てることができ、割り当てることができます。これは必要ありません。
あなたは、単に友達になれる1Lを割り当てることができます。これは、抗シリアライズコードが一致の成功を保証します。
serialVersionUIDの異なる値は、デシリアライズされたデータを読み出す影響します、あなたは1L、大きなノートLを書きます。聴衆の中に、私たち、アイドルの値は、すべての権利を改ざんしないよう、LおよびL 1を区別するために、またはバージョンのアップグレードは、古いデータに互換性がないとして、コンピュータは、あなたは、大文字と小文字の区別はありませんが、私は、問題が何であるかを知りません。

以下は、直列化インターフェイスの説明内側JDK APIドキュメントからの抜粋であります

java.io.Serializableのインタフェースを実装するクラスは、その配列を有効にしています。
クラスは、このインタフェースは、任意のシリーズまたは直列化復元をすることはありません実装されていません。
すべてのサブタイプのシーケンス缶クラス自体が直列化可能です。インタフェースの実装ので、間接的に継承することと等価です。
直列化インタフェースは、セマンティック、シリアライズを識別するために、何のメソッドやフィールドを持っていません。

serialVersionUIDのの説明

  各クラスのバージョン番号がserialVersionUIDのシリアライゼーションランタイムと呼ばれる配列、がロードされたオブジェクトの送信者と受信者を確認するデシリアライズ直列化されたオブジェクトのシーケンス番号に関連付けられてもよいですシリアライズの互換性クラス。対象の受信者のクラスのserialVersionUIDに対応するクラスの送信者は、バージョン番号が異なるロードした場合、直列化復元はによりInvalidClassExceptionを発生します。(静的フィールド(静的)にする必要があり、最終的に(決勝)long型のフィールド)文で「serialVersionUIDの」フィールドという名前の直列化可能クラスが明示的に独自のserialVersionUIDのを宣言します。

  直列化可能クラスが明示的に宣言されていないserialVersionUIDの場合は、直列化ランタイムは内「のJava™オブジェクト直列化仕様」として、そのようなクラスのさまざまな側面に基づいて算出したデフォルト値をserialVersionUIDの。しかし、強く、クラスのデフォルトのserialVersionUIDの計算の詳細は、より高い感度を持っているので、逆シリアル化プロセスのことを、コンパイラの実装によって異なる場合がありますので、すべての直列化可能クラスが明示的に、serialVersionUIDの値を宣言することをお勧めしますこれは、予期せぬによりInvalidClassExceptionを引き起こす可能性があります。したがって、別のJavaコンパイラの実装の一貫性のserialVersionUIDの値を確保するために、シリアライゼーションクラスは、明示的なserialVersionUIDの値を宣言する必要があります。役に立たない継承されたメンバーとしてのserialVersionUIDフィールド - この文が宣言クラスを指示するためにのみ適用されますので、また強く、private修飾子ショーステートメントserialVersionUIDの(可能な場合)を使用することをお勧めします。彼らは常にデフォルト値を計算する必要があるので、Arrayクラスは、明示的なserialVersionUIDのを宣言することはできませんが、クラスの配列は、要件serialVersionUIDの値と一致していません。

 

 

 

公開された118元の記事 ウォン称賛59 ビュー490 000 +

おすすめ

転載: blog.csdn.net/u012255097/article/details/103341997