インタフェースjava.io.Serializable詳細まとめ

5381 ワード

1、java.io.Serializableは、シーケンス化を表し、空のインタフェースであり、つまりこのインタフェースはメソッドを宣言していないので、このインタフェースを実装するクラスもメソッドを実装する必要はありません.
2.シーケンス化は、オブジェクトをバイトストリーム(シーケンス化)に符号化し、バイトストリームから再構成オブジェクト(逆シーケンス化)を符号化するのに用いられる.シーケンス化は、リモート通信に標準的なwire-levelプロトコルを提供します.
シーケンス化とは何ですか.
シーケンス化とは、1つのオブジェクトの状態(各プロパティ量)を保存し、適切なときに取得することです.
シーケンス化は、シーケンス化と逆シーケンス化の2つの大部分に分けられます.シーケンス化はこのプロセスの第1の部分であり、データをバイトストリームに分解してファイルに格納したり、ネットワーク上で転送したりする.逆シーケンス化とは、バイトストリームを開き、オブジェクトを再構築することです.オブジェクトのシーケンス化は、基本データ型をバイト表示に変換するだけでなく、データを復元する場合もあります.
3、クラスのインスタンスをシーケンス化するには、その宣言にimplements javaを加える.io.Serializableは、いくつかの隠れた危険性1」によってシーケンス化された後、発表されると、クラスの実現の柔軟性を弱めることになります.2』バグとセキュリティ・ホールの可能性が増加しました3」新しいバージョンがリリースされたとき、関連するテストの問題が増加しました.このインタフェースは、すべての実装クラスに特殊な(mixin)タイプを持たせ、JVMにこのクラスが安全にシリアル化できることを知らせる.
4、Beanインスタンスをネットワークで転送したり、ディスクファイルに書き込んだりする必要がある場合は、Serializableインタフェースを実現するのが最も簡単です.ObjectInputStream、ObjectOutputStreamを直接読み込んだり、書き出したりすることができます.
実用的な意味:
一:オブジェクトのシーケンス化は分散オブジェクトを実現することができる.
主な応用例:RMIは、ローカルマシン上でオブジェクトを実行するときのように、オブジェクトをシーケンス化してリモートホスト上のサービスを実行します.
二:javaオブジェクトのシーケンス化は、1つのオブジェクトのデータを保持するだけでなく、オブジェクトが参照する各オブジェクトのデータを再帰的に保存します.オブジェクト階層全体をバイトストリームに書き込み、ファイルまたはネットワークに保存できます.
接続上で転送します.オブジェクトのシーケンス化を使用して、オブジェクトの深度コピー(Depth Copy)、すなわち、オブジェクト自体と参照オブジェクト自体をコピーします.オブジェクトをシーケンス化すると、オブジェクトのシーケンス全体が得られます.
EP:
import java.io.Serializable;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
class MeTree implements Serializable {
private static final long serialVersionUID = 42L;
public MeTree left;
public MeTree right;
public int id;
public int level;
private static int count  =   0 ; 

public  MeTree( int  depth)   {

      id  = count ++ ;

      level  =  depth;

     if  (depth  >   0 )   {



        left  =   new  MeTree(depth - 1 );

        right  =   new  MeTree(depth - 1 );

    } 

 }



 public   void  print( int  levels)   {

     for  ( int  i  =   0 ; i  <  level; i ++ ) {

        System.out.print( "    " );

    System.out.println( " node  "   +  id);



     if  (level  <=  levels  &&  left  !=   null )

        left.print(levels); 

     if  (level  <=  levels  &&  right  !=   null )

        right.print(levels);

     }

 }



 public   static   void  main (String argv[])   {

     try    {

         /**/ /*  。 */ 

        FileOutputStream ostream  =   new  FileOutputStream( " MeTree.tmp " );

         /**/ /*   */ 

        ObjectOutputStream p  =   new  ObjectOutputStream(ostream);

         /**/ /*  。 */ 

        MeTree base  =   new  MeTree( 2 );

        p.writeObject(base);  //  。

         p.writeObject( " LiLy is   " );

        p.flush();

        ostream.close();     //  。



          /**/ /*  。 */ 

        FileInputStream istream  =   new  FileInputStream( " MeTree.tmp " );

        ObjectInputStream q  =   new  ObjectInputStream(istream);

         /**/ /*  ,  */ 

        MeTree new_MeTree  =  (MeTree)q.readObject();

        new_MeTree.print( 2 );   //   2 

         String name  =  (String)q.readObject();

        System.out.println( " /n " + name);

    }   catch  (Exception ex)   {

        ex.printStackTrace();

    } 

 }

}
シーケンス化の際,writeObjectとreadObjectとの間の前後順が見られる.readObjectは最初にwriteのobject readを出します.データ構造の用語では一応先進先出と言いましょう.
シーケンス化では、次の点に注意してください.
1:オブジェクトがシーケンス化されると、オブジェクトの非静的メンバー変数のみが保存され、メンバーメソッドと静的メンバー変数は保存されません.
2:オブジェクトのメンバー変数がオブジェクトである場合、そのオブジェクトのデータメンバーも保存されます.
3:シーケンス可能なオブジェクトにシーケンス不可能なオブジェクトへの参照が含まれている場合、シーケンス化操作全体が失敗し、NotSerializableExceptionが放出されます.この参照をtransientとマークすると、オブジェクトはシーケンス化されます.
また、あるオブジェクトをシーケンス化するとき、オブジェクト全体をシーケンス化することがよくあります.例えば、クラスにはデータが敏感で、シーケンス化を望んでいません.一つの方法はtransientで識別することができます.もう一つの方法はクラスで書き換えることができます.
オブジェクト内のデータ要素を復元しないようにキーtransientを指定することで、セキュリティ上の保護によく使用されます.たとえば、オブジェクトに保存されているパスワードです.
//**
Transientはクラスのメンバー変数にしか使えず、メソッドには使えない.
Transient変数はfinalとstaticではありません
Transientキー
シーケンス化プロセスを制御する場合、Javaのシーケンス化メカニズムを自動的に保存およびリカバリしたくない特定のサブオブジェクトがある可能性があります.一般に,そのサブオブジェクトにシーケンス化したくない機密情報(例えばパスワード)が含まれていると,このような状況に直面する.その情報がオブジェクトにprivate(プライベート)属性を持っていても、シーケンス化されると、ファイルを読み込んだり、ネットワーク転送をブロックしたりすることができます.
オブジェクトの敏感な部分がシーケンス化されるのを防止するために,前に示したように,自分のクラスをExternalizableとして実現する方法がある.これにより、自動シーケンス化できるものは何もなく、writeExternal()で必要な部分を明確にシーケンス化するしかありません.
ただし、Serializableオブジェクトを操作すると、すべてのシーケンス化操作が自動的に行われます.この問題を解決するために、
transient(一時的に)フィールドごとにシーケンス化を閉じることができます.「保存したり復元したりしないでください.自分で処理します」という意味です.
たとえば、Loginオブジェクトに特定のログインセッションに関する情報が含まれているとします.ログインの正当性を検証する場合、一般的にはデータを保存したいが、パスワードは含まれていない.
これを行うには、Serializableを実装し、passwordフィールドをtransientに設定するのが最も簡単です.
passwordはtransientに設定され、
ディスクに自動的に保存されません.また,自動シーケンス化メカニズムもそれを復元しようとしない.
オブジェクトが元の状態に戻るとpasswordフィールドはnullになります.注意:String()を使用してpasswordがnullであるかどうかを確認する必要があります.Stringオブジェクトをオーバーロードした「+」演算子でアセンブリし、その演算子がnullハンドルに遭遇すると、NullPointerExceptionという違反が発生するためです(新しいJavaでは、この問題を回避するコードが提供される可能性があります).
dateフィールドがディスクに保存され、ディスクから復元され、再生成されていないこともわかりました.
Externalizableオブジェクトはデフォルトではフィールドを保存しないため、transientキーワードはSerializableとともにのみ使用できます.
**//また、あるオブジェクトをシーケンス化する場合、
オブジェクト全体がシーケンス化されています.例えば、クラスにはデータが敏感で、シーケンス化を望んでいません.一つの方法はtransientで識別できます.もう一つの方法はクラスで書き換えることができます.