1

次のようなノードとポインターで表される任意のグラフがあるとします。

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

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

ここに私の質問があります:

Java では、クラスを Serializable として宣言することにより、この機能が自動的に提供されると聞いています。(私には魔法のように聞こえます!)

この記述は正しいですか?Java は自動的に BFS を実行してグラフをトラバースし、ポインターをスウィズルしますか? 言い換えれば、シリアル化/逆シリアル化はオブジェクトのクローンを作成しますか? (同じ構造で新しいノードと更新されたポインタを持つ完全に新しいオブジェクト)

はいの場合、ポインタをコピーしたいだけの場合はどうなりますか? 元のポインターを保持するためだけにオブジェクトをシリアル化したい場合はどうすればよいですか?

これについてのコメントをお待ちしております。:-)

4

2 に答える 2

1

私はそれがあなたがそれをどのように考えているかではないと思いますが、ほとんどです。Java でのシリアル化はかなり不透明なプロセスです。それについて本当に知っておく必要があるのは、クラスとそのメンバーのすべての型が implement であると仮定するとSerializable、Java はそれをバイトのストリームに変換する方法と、そのストリームからオブジェクトのインスタンスを再作成する方法を知っているということです。逆シリアル化するように依頼します。

C++ から来たので、最初は黒魔術のように思えました。私はプロセス全体に懐疑的で、JVM が処理してくれるとは信じていませんでした。C++ では、単純なオブジェクトについてこれを実行するのに十分な知識がないからです。しかし、Java からデータにアクセスするだけでよいと仮定すると、実際には非常に便利です。

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

もう 1 つ: 変数を として宣言すると、変数はtransient保存されず、自分で復元する必要があります。これは、スペースを無駄にしたくない特定の値をキャッシュするフィールドがある場合や、機密データが含まれるフィールドを放置したくない場合に役立ちます。ただし、自分で復元することを忘れないでください。

于 2012-02-29T01:16:29.880 に答える
1

最初に最後の質問にお答えします。シリアル化の目的は、オブジェクト グラフをメモリに複製することではありません。ファイルへの保存やネットワーク経由での送信などを行うために、オブジェクト グラフをバイト ストリームに変換します。デシリアライゼーション プロセスは、別のコンピューターで、別の時間に、別のプロセスで、または Java 以外のプログラムによって実行される可能性があるため、以前と同じオブジェクトへの参照を取得することは合理的な期待ではありません。保存され、後で復元されるのはオブジェクト グラフの構造と内容であり、メモリ内アドレスではありません。まさにこの理由から、すべてのオブジェクトをシリアライズ可能にすることは意味がありません。たとえば、a のシリアル化Threadは、プログラムの現在のインスタンスの外では意味がないため、役に立ちません。

自動シリアル化の背後にある魔法はそれほど複雑ではありません。シリアライゼーションとデシリアライゼーションの動作を正確に制御するために独自のクラス用に記述できるカスタム シリアライゼーション メソッドを無視すると、システムはバイト ストリームを生成するためにオブジェクト グラフを効果的にトラバースします。このトラバーサルは通常、BFS ではなく DFS として行われます。基本的に、オブジェクトへの参照を渡して、オブジェクトをシリアライズするよう Java に要求します。その参照は、オブジェクト グラフのルートとして機能します。そこから、Java はそのオブジェクトのフィールドを再帰的にシリアライズします。もちろん、循環参照を追跡し、出力ストリームに適切なマーキングを書き出すので、デシリアライザーはポインターを接続して以前と同じように構造を再作成できます。

于 2012-02-29T01:21:04.407 に答える