オブジェクトのシリアル化とは何ですか?
-
19-08-2019 - |
質問
<!> quot; object serialization <!> quot;とはどういう意味ですか?例を挙げて説明してもらえますか?
解決
シリアル化とは、オブジェクトを一連のバイトに変換することです。そのため、オブジェクトを永続ストレージに簡単に保存したり、通信リンクを介してストリーミングしたりできます。その後、バイトストリームを逆シリアル化して、元のオブジェクトのレプリカに変換できます。
他のヒント
シリアル化は、オブジェクトインスタンスをバイトシーケンスに変換するプロセスと考えることができます(これは、実装によってはバイナリである場合も、そうでない場合もあります)。
1つのJVMから別のJVMなど、ネットワークを介して1つのオブジェクトデータを送信する場合に非常に便利です。
Javaでは、シリアル化メカニズムはプラットフォームに組み込まれていますが、 Serializable インターフェースを実装して、オブジェクトをシリアル化可能にする必要があります。
また、属性を transient としてマークすることにより、オブジェクト内の一部のデータのシリアル化を防ぐことができます。
最後に、デフォルトのメカニズムをオーバーライドして、独自のメカニズムを提供できます。これはいくつかの特別な場合に適しています。これを行うには、 Javaの非表示機能のいずれかを使用します。 p>
シリアル化されるのは<!> quot; value <!> quot;であることに注意することが重要です。クラス定義ではなく、オブジェクトまたはコンテンツの。したがって、メソッドはシリアル化されません。
読みやすくするためのコメント付きの非常に基本的なサンプルを次に示します。
import java.io.*;
import java.util.*;
// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {
// These attributes conform the "value" of the object.
// These two will be serialized;
private String aString = "The value of that string";
private int someInteger = 0;
// But this won't since it is marked as transient.
private transient List<File> unInterestingLongLongList;
// Main method to test.
public static void main( String [] args ) throws IOException {
// Create a sample object, that contains the default values.
SerializationSample instance = new SerializationSample();
// The "ObjectOutputStream" class has the default
// definition to serialize an object.
ObjectOutputStream oos = new ObjectOutputStream(
// By using "FileOutputStream" we will
// Write it to a File in the file system
// It could have been a Socket to another
// machine, a database, an in memory array, etc.
new FileOutputStream(new File("o.ser")));
// do the magic
oos.writeObject( instance );
// close the writing.
oos.close();
}
}
このプログラムを実行すると、ファイル<!> quot; o.ser <!> quot;作成され、背後で何が起こったかを見ることができます。
たとえば someInteger の値を Integer.MAX_VALUE に変更した場合、出力を比較して違いを確認できます。
その違いを正確に示すスクリーンショットは次のとおりです。
違いを見つけられますか? ;)
Javaシリアル化には追加の関連フィールドがあります: serialversionUID すでに長すぎてカバーできません。
6年前の質問に答える勇気があり、Javaを初めて使用する人に非常に高いレベルの理解を追加する
シリアル化とは
オブジェクトをバイトに変換し、バイトをオブジェクトに戻す(逆シリアル化)。
シリアル化はいつ使用されますか
オブジェクトを永続化する場合。 JVMの寿命を超えてオブジェクトを存在させたい場合。
実世界の例:
ATM:アカウント所有者がATMを介してサーバーからお金を引き出しようとすると、引き出しの詳細などのアカウント所有者情報がシリアル化され、サーバーに送信されます。
Javaでのシリアル化の実行方法
-
実装
java.io.Serializable
インターフェース(マーカーインターフェースなので実装するメソッドはありません)。 -
オブジェクトの永続化:
java.io.ObjectOutputStream
クラスを使用します。これは、下位レベルのバイトストリームのラッパーであるフィルターストリームです(ファイルシステムにObjectを書き込むか、ネットワークワイヤを介してフラット化されたオブジェクトを転送し、再構築するには)反対側)。-
writeObject(<<instance>>)
-オブジェクトを書き込む -
readObject()
-シリアル化されたオブジェクトを読み取る
-
覚えておいてください:
オブジェクトをシリアル化すると、オブジェクトの状態のみが保存され、オブジェクトのクラスファイルやメソッドは保存されません。
2バイトのオブジェクトをシリアル化すると、51バイトのシリアル化されたファイルが表示されます。
オブジェクトのシリアル化と逆シリアル化の手順。
Answer for:どのようにして51バイトのファイルに変換しましたか?
- まず、シリアル化ストリームのマジックデータを書き込みます(STREAM_MAGIC = <!> quot; AC ED <!> quot;およびSTREAM_VERSION = JVMのバージョン)。
- 次に、インスタンスに関連付けられたクラスのメタデータ(クラスの長さ、クラスの名前、serialVersionUID)を書き出します。
- 次に、
java.lang.Object
が見つかるまでスーパークラスのメタデータを再帰的に書き出します。 - 次に、インスタンスに関連付けられている実際のデータから始めます。
- 最後に、メタデータから実際のコンテンツまで、インスタンスに関連付けられたオブジェクトのデータを書き込みます。
Javaシリアル化に関する詳細な情報に関心がある場合は、このリンクを確認してください。 。
編集:もう1つの優れたリンクを読む。
これにより、いくつかのよくある質問に答えます:
-
クラスのフィールドをシリアル化しない方法。
回答:一時的なキーワードを使用 -
子クラスがシリアル化されると、親クラスはシリアル化されますか?
回答:いいえ、親がSerializableインターフェイスを拡張していない場合、親フィールドはシリアル化されません。 -
親がシリアル化されると、子クラスはシリアル化されますか?
回答:はい、デフォルトでは子クラスもシリアル化されます。 -
子クラスがシリアル化されないようにする方法
をスローします
回答:a。 writeObjectおよびreadObjectメソッドをオーバーライドし、NotSerializableException
。
b。子クラスのすべてのフィールドを一時的にマークすることもできます。
- Thread、OutputStreamとそのサブクラス、Socketなどのシステムレベルのクラスの中には、シリアル化できないものがあります。
シリアル化は<!> quot; live <!> quot;オブジェクトをメモリ内に格納し、それをどこかに保存できる形式に変換します(メモリ、ディスクなど)。後で<!> quot; deserialized <!> quot;ライブオブジェクトに戻ります。
@OscarRyzの表示方法が気に入りました。ここでは、最初に作成されたシリアル化のストーリーを継続しています@amitgupta。
ロボットのクラス構造を知っていて、データをシリアル化したにもかかわらず、地球の科学者はロボットを動作させるデータをシリアル化解除できませんでした。
Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:
火星の科学者は完全な支払いを待っていました。支払いが完了すると、火星の科学者は serialversionUID を地球の科学者と共有しました。地球の科学者はロボットクラスに設定し、すべてが正常になりました。
自分のブログの2セント:
シリアル化の詳細な説明 :(自分のブログ)
シリアル化:
シリアル化は、オブジェクトの状態を永続化するプロセスです。これは、バイトシーケンスの形式で表され、保存されます。これはファイルに保存できます。ファイルからオブジェクトの状態を読み取り、復元するプロセスは、デシリアライゼーションと呼ばれます。
シリアル化の必要性
現代のアーキテクチャでは、オブジェクトの状態を保存してから取得する必要が常にあります。たとえば、Hibernateでは、オブジェクトを保存するには、クラスをSerializableにする必要があります。オブジェクトの状態がバイト形式で保存されると、別のシステムに転送できるようになり、その状態から読み取り、クラスを取得できるようになります。オブジェクトの状態は、データベース、別のjvm、または別のコンポーネントから取得できます。シリアル化の助けを借りて、オブジェクトの状態を取得できます。
コード例と説明:
まず、アイテムクラスを見てみましょう:
public class Item implements Serializable{
/**
* This is the Serializable class
*/
private static final long serialVersionUID = 475918891428093041L;
private Long itemId;
private String itemName;
private transient Double itemCostPrice;
public Item(Long itemId, String itemName, Double itemCostPrice) {
super();
this.itemId = itemId;
this.itemName = itemName;
this.itemCostPrice = itemCostPrice;
}
public Long getItemId() {
return itemId;
}
@Override
public String toString() {
return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]";
}
public void setItemId(Long itemId) {
this.itemId = itemId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public Double getItemCostPrice() {
return itemCostPrice;
}
public void setItemCostPrice(Double itemCostPrice) {
this.itemCostPrice = itemCostPrice;
}
}
上記のコードでは、 Item クラスが Serializable を実装していることがわかります。
これは、クラスをシリアル化できるようにするインターフェイスです。
今、 serialVersionUID という変数がLong変数に初期化されていることがわかります。この数は、クラスの状態とクラス属性に基づいてコンパイラーによって計算されます。これは、ファイルからオブジェクトの状態を読み取るときに、jvmがオブジェクトの状態を識別するのに役立つ番号です。
そのためには、オラクルの公式ドキュメントをご覧ください:
シリアル化ランタイムは、各シリアル化可能クラスに関連付けられます serialVersionUIDと呼ばれるバージョン番号。 シリアル化の送信者と受信者が オブジェクトは、そのオブジェクトと互換性のあるクラスをロードしました シリアル化に関して。受信者がクラスをロードした場合 異なるserialVersionUIDを持つオブジェクト 対応する送信者のクラス、逆シリアル化の結果は InvalidClassException。直列化可能クラスは独自のクラスを宣言できます という名前のフィールドを宣言することによって明示的にserialVersionUID <!> quot; serialVersionUID <!> quot;静的で、finalで、long型である必要があります。 ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;もし 直列化可能クラスは、serialVersionUIDを明示的に宣言しません。 シリアル化ランタイムはデフォルトを計算します のさまざまな側面に基づいたそのクラスのserialVersionUID値 Java(TM)Object Serializationで説明されているクラス 仕様。ただし、すべての 直列化可能クラスは、serialVersionUID値を明示的に宣言します。 デフォルトのserialVersionUID計算はクラスに非常に敏感です コンパイラーの実装によって異なる可能性のある詳細 したがって、予期しないInvalidClassExceptionsが発生します 逆シリアル化。したがって、一貫性のあるserialVersionUIDを保証するには さまざまなJavaコンパイラー実装にわたる値、シリアル化可能 クラスは明示的なserialVersionUID値を宣言する必要があります。それも 明示的なserialVersionUID宣言では、 このような宣言は次のものにのみ適用されるため、可能な場合はprivate修飾子 すぐに宣言するクラス-serialVersionUIDフィールドは 継承されたメンバーとして有用です。
気付いた場合は、使用した別のキーワードである transient があります。
フィールドがシリアル化可能でない場合、一時的にマークする必要があります。ここでは、 itemCostPrice を一時的なものとしてマークし、ファイルに書き込まないようにします
次に、ファイルにオブジェクトの状態を書き込み、そこから読み取る方法を見てみましょう。
public class SerializationExample {
public static void main(String[] args){
serialize();
deserialize();
}
public static void serialize(){
Item item = new Item(1L,"Pen", 12.55);
System.out.println("Before Serialization" + item);
FileOutputStream fileOut;
try {
fileOut = new FileOutputStream("/tmp/item.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(item);
out.close();
fileOut.close();
System.out.println("Serialized data is saved in /tmp/item.ser");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void deserialize(){
Item item;
try {
FileInputStream fileIn = new FileInputStream("/tmp/item.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
item = (Item) in.readObject();
System.out.println("Serialized data is read from /tmp/item.ser");
System.out.println("After Deserialization" + item);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
上記では、オブジェクトのシリアル化と逆シリアル化の例を見ることができます。
そのために、2つのクラスを使用しました。オブジェクトをシリアル化するために、ObjectOutputStreamを使用しました。ファイルにオブジェクトを書き込むためにメソッドwriteObjectを使用しました。
逆シリアル化には、ファイルからオブジェクトを読み取るObjectInputStreamを使用しました。 readObjectを使用して、ファイルからオブジェクトデータを読み取ります。
上記のコードの出力は次のようになります。
Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55]
Serialized data is saved in /tmp/item.ser
After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null]
デシリアライズされたオブジェクトの itemCostPrice は、記述されていないため null であることに注意してください。
この記事のパートIでは、Javaシリアル化の基本について既に説明しました。
それでは、それとそれがどのように機能するかについて深く議論しましょう。
まず serialversionuidから始めましょう。
serialVersionUID は、Serializableクラスのバージョン管理として使用されます。
serialVersionUIDを明示的に宣言しない場合、JVMはSerializableクラスのさまざまなプロパティに基づいて自動的に宣言します。
serialversionuidを計算するJavaのアルゴリズム(詳細はこちら)
- クラス名。
- 32ビット整数として記述されたクラス修飾子。
- 名前でソートされた各インターフェイスの名前。
- フィールド名でソートされたクラスの各フィールド(プライベート静的フィールドとプライベート一時フィールドを除く:フィールドの名前。 32ビット整数として記述されたフィールドの修飾子。記述子 フィールドの。
- クラス初期化子が存在する場合は、次のように書きます:メソッドの名前、。
- メソッドの修飾子、java.lang.reflect.Modifier.STATIC、32ビット整数として書き込まれます。
- メソッドの記述子、()V。
- メソッド名とシグネチャでソートされた各非プライベートコンストラクターの場合:メソッドの名前。の修飾子 32ビット整数として記述されたメソッド。メソッドの記述子。
- メソッド名と署名でソートされた非プライベートメソッドごと:メソッドの名前。として記述されたメソッドの修飾子 32ビット整数。メソッドの記述子。
- SHA-1アルゴリズムは、DataOutputStreamによって生成されたバイトストリームで実行され、5つの32ビット値sha [0..4]を生成します。の ハッシュ値は、1番目と2番目の32ビット値から組み立てられます SHA-1メッセージダイジェスト。メッセージダイジェストの結果、5 32ビットワードH0 H1 H2 H3 H4、という名前の5つのint値の配列 sha、ハッシュ値は次のように計算されます:
long hash = ((sha[0] >>> 24) & 0xFF) |
> ((sha[0] >>> 16) & 0xFF) << 8 |
> ((sha[0] >>> 8) & 0xFF) << 16 |
> ((sha[0] >>> 0) & 0xFF) << 24 |
> ((sha[1] >>> 24) & 0xFF) << 32 |
> ((sha[1] >>> 16) & 0xFF) << 40 |
> ((sha[1] >>> 8) & 0xFF) << 48 |
> ((sha[1] >>> 0) & 0xFF) << 56;
Javaのシリアル化アルゴリズム
オブジェクトをシリアル化するアルゴリズムは次のとおりです。
1.インスタンスに関連付けられたクラスのメタデータを書き出します。
2.スーパークラスの説明を java.lang.object が見つかるまで再帰的に書き出します。
3.メタデータ情報の書き込みが完了すると、インスタンスに関連付けられている実際のデータから開始します。でも今回は 最上位のスーパークラスから開始します。
4.インスタンスに関連付けられたデータを、最小のスーパークラスから最も派生したクラスまで再帰的に書き込みます。
留意点:
-
クラスの静的フィールドはシリアル化できません。
public class A implements Serializable{ String s; static String staticString = "I won't be serializable"; }
-
serialversionuidが読み取りクラスで異なる場合、
InvalidClassException
例外をスローします。 -
クラスがシリアライズ可能を実装する場合、そのサブクラスもすべてシリアライズ可能になります。
public class A implements Serializable {....}; public class B extends A{...} //also Serializable
-
クラスに別のクラスの参照がある場合、すべての参照は直列化可能でなければなりません。そうでない場合、直列化プロセスは実行されませんmed。そのような場合、実行時に NotSerializableException がスローされます。
例:
public class B{
String s,
A a; // class A needs to be serializable i.e. it must implement Serializable
}
シリアル化は、javaでオブジェクトを永続化することを意味します。オブジェクトの状態を保存し、後で状態を再構築する(別のJVMにある可能性がある)場合は、シリアル化を使用できます。
オブジェクトのプロパティは保存されるだけであることに注意してください。オブジェクトを再度復活させたい場合は、メンバー変数のみが保存され、メンバー関数は保存されないため、クラスファイルが必要です。
eg:
ObjectInputStream oos = new ObjectInputStream(
new FileInputStream( new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();
Searializableは、クラスがシリアル化可能であることを示すマーカーインターフェイスです。マーカーインターフェイスは、それが単なる空のインターフェイスであることを意味し、そのインターフェイスを使用すると、このクラスをシリアル化できることをJVMに通知します。
シリアル化は、オブジェクトの状態をビットに変換して、ハードドライブに保存できるようにするプロセスです。同じオブジェクトをデシリアライズすると、後でその状態が保持されます。オブジェクトのプロパティを手動で保存することなく、オブジェクトを再作成できます。
シリアル化とは、オブジェクトを記憶媒体(ファイル、メモリバッファーなど)に保存するプロセス、またはネットワーク接続を介してバイナリ形式で送信するプロセスです。シリアル化されたオブジェクトはJVMに依存せず、任意のJVMで再シリアル化できます。この場合、<!> quot; in memory <!> quot; Javaオブジェクトの状態はバイトストリームに変換されます。ユーザーはこのタイプのファイルを理解できません。これは、JVM(Java Virtual Machine)によって再利用される特別なタイプのオブジェクトです。オブジェクトをシリアル化するこのプロセスは、オブジェクトのデフレートまたはマーシャリングとも呼ばれます。
シリアル化されるオブジェクトは、java.io.Serializable
インターフェイスを実装する必要があります。
オブジェクトのデフォルトのシリアル化メカニズムは、オブジェクトのクラス、クラス署名、およびすべての非一時フィールドと非静的フィールドの値を書き込みます。
class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,
ObjectOutput
インターフェースはDataOutput
インターフェースを拡張し、オブジェクトをシリアル化し、ファイルにバイトを書き込むためのメソッドを追加します。 ObjectOutputStream
はjava.io.OutputStream
を拡張し、ObjectOutputStream( )
インターフェイスを実装します。オブジェクト、配列、その他の値をストリームにシリアル化します。したがって、FileOuputStream
のコンストラクタは次のように記述されます。
ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));
上記のコードは、ObjectInputStream
のインスタンスをパラメーターとして使用するjava.io.InputStream
コンストラクターでObjectInput
クラスのインスタンスを作成するために使用されています。
FileInputStream
インターフェイスを使用するには、ObjectInputStream()
クラスを実装します。 <=>は、オブジェクトをシリアル化するために構築されます。
javaでのオブジェクトのデシリアライズ
シリアル化の反対の操作は、逆シリアル化と呼ばれます。つまり、一連のバイトからデータを抽出することは、逆シリアル化として知られています。これは、インフレートまたはアンマーシャリングとも呼ばれます。
<=>は<=>を拡張し、<=>インターフェイスを実装します。入力ストリームからオブジェクト、配列、その他の値をデシリアライズします。したがって、<=>のコンストラクタは次のように記述されます。
ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));
プログラムの上記のコードは、<=>クラスのインスタンスを作成して、<=>クラスによってシリアル化されたファイルを逆シリアル化します。上記のコードは、<=>コンストラクターに入力ストリームが必要なため、逆シリアル化する必要がある指定されたファイルオブジェクトを保持する<=>クラスのインスタンスを使用してインスタンスを作成します。
Java オブジェクトのシリアル化
Serialization
は、Javaオブジェクトのグラフをストレージ(to disk file
)または送信(across a network
)のバイト配列に変換するメカニズムです。デシリアライゼーションを使用して、オブジェクトのグラフを復元します。
オブジェクトのグラフは、参照共有メカニズムを使用して正しく復元されます。 ただし、保存する前に、input-file / networkのserialVersionUIDと.classファイルのserialVersionUIDが同じかどうかを確認します。そうでない場合は、java.io.InvalidClassException
をスローします。
各バージョン付きクラスは、ストリームを書き込むことができ、読み取り可能な元のクラスバージョンを識別する必要があります。たとえば、バージョン管理されたクラスは以下を宣言する必要があります。
serialVersionUIDの構文
// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L; private static final long serialVersionUID = 3487495895819393L;
serialVersionUID は、シリアル化プロセスに不可欠です。ただし、開発者がJavaソースファイルに追加することはオプションです。 serialVersionUIDが含まれていない場合、シリアル化ランタイムはserialVersionUIDを生成し、クラスに関連付けます。シリアル化されたオブジェクトには、このserialVersionUIDと他のデータが含まれます。
注-すべてのシリアライズ可能なクラスが明示的にserialVersionUID、 since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations
を宣言することを強くお勧めします。失敗します。
Javaオブジェクトはシリアル化のみ可能です。クラスまたはそのスーパークラスのいずれかが java.io.Serializable インターフェースを実装する場合 またはそのサブインターフェース、 java.io.Externalizable 。
-
オブジェクトを正常にシリアル化するには、クラスが java.io.Serializableインターフェイスを実装する必要があります。 Serializableはマーカーインターフェイスであり、それを実装するクラスにSerializable動作を追加する必要があることをコンパイラに通知するために使用されます。 ここでは、Java仮想マシン(JVM)が自動シリアル化を担当します。
一時的なキーワード:
java.io.Serializable interface
オブジェクトのシリアル化中に、オブジェクトの特定のデータメンバーをシリアル化したくない場合は、transient修飾子を使用できます。 transientキーワードは、そのデータメンバーのシリアル化を防ぎます。
- 一時的または静的として宣言されたフィールドは、シリアル化プロセスによって無視されます。
+--------------+--------+-------------------------------------+ | Flag Name | Value | Interpretation | +--------------+--------+-------------------------------------+ | ACC_VOLATILE | 0x0040 | Declared volatile; cannot be cached.| +--------------+--------+-------------------------------------+ |ACC_TRANSIENT | 0x0080 | Declared transient; not written or | | | | read by a persistent object manager.| +--------------+--------+-------------------------------------+
class Employee implements Serializable { private static final long serialVersionUID = 2L; static int id; int eno; String name; transient String password; // Using transient keyword means its not going to be Serialized. }
-
Externalizableインターフェイスを実装すると、オブジェクトは、オブジェクトのシリアル化された形式の内容と形式を完全に制御できるようになります。 Externalizableインターフェイスのメソッド、writeExternalおよびreadExternalは、オブジェクトの状態を保存および復元するために呼び出されます。クラスによって実装されると、次を使用して独自の状態を読み書きできます。ObjectOutputおよびObjectInputのすべてのメソッド。発生するバージョニングを処理するのはオブジェクトの責任です。
class Emp implements Externalizable { int eno; String name; transient String password; // No use of transient, we need to take care of write and read. @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeInt(eno); out.writeUTF(name); //out.writeUTF(password); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { this.eno = in.readInt(); this.name = in.readUTF(); //this.password = in.readUTF(); // java.io.EOFException } }
-
java.io.Serializableまたはjava.io.Externalizableインターフェイスをサポートするオブジェクトのみが
written to
/read from
ストリームになります。各シリアル化可能なオブジェクトのクラスは、クラス名とクラスのシグネチャ、オブジェクトのフィールドと配列の値、および初期オブジェクトから参照される他のオブジェクトのクロージャーを含めてエンコードされます。
ファイルのシリアル化可能な例
public class SerializationDemo {
static String fileName = "D:/serializable_file.ser";
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
Employee emp = new Employee( );
Employee.id = 1; // Can not Serialize Class data.
emp.eno = 77;
emp.name = "Yash";
emp.password = "confidential";
objects_WriteRead(emp, fileName);
Emp e = new Emp( );
e.eno = 77;
e.name = "Yash";
e.password = "confidential";
objects_WriteRead_External(e, fileName);
/*String stubHost = "127.0.0.1";
Integer anyFreePort = 7777;
socketRead(anyFreePort); //Thread1
socketWrite(emp, stubHost, anyFreePort); //Thread2*/
}
public static void objects_WriteRead( Employee obj, String serFilename ) throws IOException{
FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
ObjectOutputStream objectOut = new ObjectOutputStream( fos );
objectOut.writeObject( obj );
objectOut.close();
fos.close();
System.out.println("Data Stored in to a file");
try {
FileInputStream fis = new FileInputStream( new File( serFilename ) );
ObjectInputStream ois = new ObjectInputStream( fis );
Object readObject;
readObject = ois.readObject();
String calssName = readObject.getClass().getName();
System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException
Employee emp = (Employee) readObject;
System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);
ois.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void objects_WriteRead_External( Emp obj, String serFilename ) throws IOException {
FileOutputStream fos = new FileOutputStream(new File( serFilename ));
ObjectOutputStream objectOut = new ObjectOutputStream( fos );
obj.writeExternal( objectOut );
objectOut.flush();
fos.close();
System.out.println("Data Stored in to a file");
try {
// create a new instance and read the assign the contents from stream.
Emp emp = new Emp();
FileInputStream fis = new FileInputStream(new File( serFilename ));
ObjectInputStream ois = new ObjectInputStream( fis );
emp.readExternal(ois);
System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);
ois.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
ネットワーク上のシリアル化可能な例
異なるアドレススペース間でのオブジェクトの状態の分散コンピュータ、またはネットワークを介して接続されている複数のコンピュータでも、データを共有してメソッドを呼び出すことで連携して動作します。
/**
* Creates a stream socket and connects it to the specified port number on the named host.
*/
public static void socketWrite(Employee objectToSend, String stubHost, Integer anyFreePort) {
try { // CLIENT - Stub[marshalling]
Socket client = new Socket(stubHost, anyFreePort);
ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
out.writeObject(objectToSend);
out.flush();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// Creates a server socket, bound to the specified port.
public static void socketRead( Integer anyFreePort ) {
try { // SERVER - Stub[unmarshalling ]
ServerSocket serverSocket = new ServerSocket( anyFreePort );
System.out.println("Server serves on port and waiting for a client to communicate");
/*System.in.read();
System.in.read();*/
Socket socket = serverSocket.accept();
System.out.println("Client request to communicate on port server accepts it.");
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Employee objectReceived = (Employee) in.readObject();
System.out.println("Server Obj : "+ objectReceived.name );
socket.close();
serverSocket.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
@see
シリアル化は、Javaオブジェクトをバイト配列に変換してから、状態を保持したままオブジェクトに戻すプロセスです。ネットワークを介したオブジェクトの送信やディスクへのキャッシュなど、さまざまなことに役立ちます。
プロセスのプログラミングの部分を非常によく説明しているこの短い記事に移動してから Serializableに移動しますjavadoc 。 この関連する質問。
ファイルをオブジェクトとして返す: http://www.tutorialspoint.com/java/ java_serialization.htm
import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try
{
FileOutputStream fileOut =
new FileOutputStream("/tmp/employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
}catch(IOException i)
{
i.printStackTrace();
}
}
}
import java.io.*;
public class DeserializeDemo
{
public static void main(String [] args)
{
Employee e = null;
try
{
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
| * |クラスのシリアル化:オブジェクトをバイトに変換し、バイトをオブジェクトに戻します(逆シリアル化)。
class NamCls implements Serializable
{
int NumVar;
String NamVar;
}
| = <!> gt;オブジェクトのシリアル化は、オブジェクトの状態をバイトのストリームに変換するプロセスです。
- |-<!> gt; JVMの存続期間を超えてオブジェクトを存在させる場合に実装します。
- |-<!> gt;シリアル化されたオブジェクトはデータベースに保存できます。
- |-<!> gt;シリアル化可能なオブジェクトは人間が読むことも理解することもできないため、セキュリティを実現できます。
| = <!> gt;オブジェクトのデシリアライゼーションは、オブジェクトの状態を取得してオブジェクト(java.lang.Object)に保存するプロセスです。
- |-<!> gt;状態を保存する前に、input-file / networkのserialVersionUIDと.classファイルのserialVersionUIDが同じかどうかを確認します。
<!> amp; nbsp <!> amp; nbspjava.io.InvalidClassException。
をスローしない場合
| = <!> gt; Javaオブジェクトは、そのクラスまたはそのスーパークラスのいずれかである場合にのみシリアル化可能です
- java.io.Serializableインターフェースまたは
を実装します
- そのサブインターフェース、java.io.Externalizable。
| = <!> gt;クラスの静的フィールドはシリアル化できません。
class NamCls implements Serializable
{
int NumVar;
static String NamVar = "I won't be serializable";;
}
| = <!> gt;クラスの変数をシリアル化したくない場合は、一時的なキーワードを使用します
class NamCls implements Serializable
{
int NumVar;
transient String NamVar;
}
| = <!> gt;クラスがシリアライズ可能を実装する場合、そのすべてのサブクラスもシリアライズ可能になります。
| = <!> gt;クラスに別のクラスの参照がある場合、すべての参照はSerializableである必要があります。そうでない場合、シリアル化プロセスは実行されません。そのような場合、実行時に
NotSerializableExceptionがスローされます。