2012-02-29 10 views
1

は、私たちがこのようなノードとポインタによって表される任意のグラフがあるとします。今Javaによる自動ポインタスウィズリング?

class Node 
{ 
    public ValueType data; 
    public ArrayList<Node> adj; 
} 

を、私はそれのコピーを取るか、書き込み/ディスク(AKAシリアライズ/デシリアライズ)でそれを読んでもらいたいです。私はまた、それが検索アルゴリズム+連想配列を使用して行うことができることを知っています。そして、この方法はswizzlingと呼ばれています。ここで

は私の質問に行く:

私はJavaでシリアライズとしてクラスを宣言することで、この機能は自動的にあなたのために提供されていることを聞きました。 (私には魔法のように聞こえるよ!)

この文は正しいですか? Javaは自動的にBFSを実行してグラフを走査し、ポインタを揺らしますか?つまり、私のためにオブジェクトをシリアル化/デシリアライズしてオブジェクトを複製しますか? (構造は全く同じですが、新しいノードと更新されたポインタを持つまったく新しい新しいオブジェクト)

ある場合は、ポインタをコピーしたいだけの場合はどうなりますか?元のポインタを保持するためだけにオブジェクトを直列化したいのですが?

私はこれに関するコメントを感謝します。 :-)

+0

Javaには未処理のポインタがありません。実際のメモリアドレスにアクセスすることはできません。あなたはオブジェクトへの参照を持っています(実際にはポインタですが、そのことを誰にも知らせず、C++参照と混同しないでください)。 –

+0

こちらをご覧ください。もしあなたが見るなら、それはすべて文書の中にあります。 –

+0

@BrianRoach:間違って申し訳ありません。私はC++の考え方をしていました。 – Nima

答えて

1

私はまずあなたの最後の質問にお答えします。直列化の目的は、オブジェクトグラフをメモリに複製することではありません。これは、オブジェクトグラフをバイトストリームに変換して、ファイルに保存するか、ワイヤを介して送信するなどの作業を行います。逆シリアル化プロセスは、別のコンピュータ、別の時間、異なるプロセス、または非Javaプログラムによって実行される可能性があるため、以前と同じオブジェクトへの参照を取得することは妥当な期待ではありません。メモリ内のアドレスではなく、保存され、後で復元されるのはオブジェクトグラフの構造と内容です。この理由から、すべてのオブジェクトがシリアライズ可能であるとは限りません。たとえば、Threadをシリアル化することは有用ではありません。なぜなら、プログラムの現在のインスタンス以外では意味がないからです。

自動シリアル化の背後にある魔法はあまり複雑ではありません。はい、システムは、バイトストリームを生成するために効果的にオブジェクトグラフをトラバースします。このトラバーサルは、通常BFSではなくDFSとして行われます。基本的には、オブジェクトのシリアル化をJavaに依頼し、そのオブジェクトへの参照を渡します。その参照はオブジェクトグラフのルートとして機能します。そこから、Javaはそのオブジェクトのフィールドを再帰的にシリアル化します。もちろん、循環参照を追跡し、適切なマーキングを出力ストリームに書き出すので、デシリアライザはポインタを連結して以前と同じように構造を再作成することができます。

+1

C++は「how ?!:O」と思って歩いていて、Javaはウィンクしました。 奇跡的!私は最近、文字列のスイッチケースを追加した言語を意味します。 – Nima

1

私はそれがあなたがそれについて考えている方法だとは思えませんが、かなりです。 Javaでのシリアライゼーションは、かなり不透明なプロセスです。クラスとそのメンバのすべての型が、Serializableを実装していると仮定すれば、それをバイトストリームに変換する方法と、そのストリームからオブジェクトのインスタンスを再作成する方法はJavaが知っているだけです脱直列化するように求めます。

C++から来て、最初は黒い魔法のようでした。私はプロセス全体に懐疑的であり、C++ではこれを行うための単純なオブジェクトについて十分な知識がないため、JVMが私の世話をするのを本当に信用していませんでした。しかし、あなたはJavaからデータにアクセスする必要があるだけで、実際には本当にうれしいです。

基本的には、ポインタやその下に使用されるアルゴリズムについて心配する必要はありません。あなたはオブジェクトを書くように指示し、後でそれを読み返すように指示します。そして、あなたは本質的に以前と同じメモリ内構造を持っています。

もう1つ:変数をtransientと宣言すると、その変数は保存されず、自分で復元する必要があります。これは、スペースを浪費したくない特定の値をキャッシュするフィールドや、偽りのないデータがあるフィールドがある場合に便利です。しかし、あなたはそれを自分で復元することを覚えておく必要があります。

関連する問題