Javaは、シリアル化と呼ばれるメカニズムを提供します。Javaオブジェクトは、オブジェクトのデータ、およびオブジェクトに保存されたデータ型を含む秩序ある形式またはバイトシーケンスを介して永続的です。
したがって、オブジェクトをシリアル化した場合、オブジェクトの種類やその他の情報を使用して読み取り、非アクティブ化し、最後にオブジェクトのプロトタイプを取得できます。
ObjectInputStreamおよびObjectOutputStreamオブジェクトは、シリアル化やバックシーケンシャルメソッドを含む高レベルのストリーミングオブジェクトです。
ObjectPutStreamには、シリアル化されたオブジェクトの多くの方法があります。
private void writeObject(objectOutputStream OS)IOException {}をスローする
同様のObjectInputStreamは、次の方法を提供します。
プライベートボイドブランド(ObjectInputStream IS)はiOException、classNotFoundException {}をスローします
では、どこでシリアル化する必要がありますか?シリアル化は通常、ネットワーク伝送データを使用するか、オブジェクトをファイルに保存します。ここに記載されているデータは、テキストではなくオブジェクトです。
問題は、ネットワークアーキテクチャとハードディスクがバイナリとバイトのみを識別でき、Javaオブジェクトを認識できないことです。
シリアル化は、Javaオブジェクトの値/状態をバイトに変換して、ネットワークを介して送信または保存することです。さらに、依存関係のシリアル化は、バイトコードを読み取り、Javaオブジェクトに変換することです。
SerialVersionUidコンセプト
SerialVersionUidは、同じオブジェクト(シリアル化で使用できる)を脱出プロセス中にロードできることを確認するために使用されます。 SerialVersionUidは、オブジェクトのバージョン制御です。 Javaシリアル化のSerialVersionUidを参照して、より多くの情報を取得できます。
シリアル化用:
手順は次のとおりです。
リストを見てみましょう:
src-> org.arpit.javapostsforningでemployee.javaを作成します
1.EmployeE.Java
org.arpit.javapostsforning。 = EmployeeId;} public string getemployeename(){return employeeName;} public void setemployeename(string equirename){this.employeena me = equipeename;} public string getdeppartment(){return department;} public void setepment(String Department){これ。 depapartment = department;}}
ご覧のとおり、クラスをシリアル化する必要がある場合は、シリアル化可能なインターフェイスを実装する必要があります。
Javaのマーカーインターフェイスは、フィールドまたはメソッドのないインターフェイスです。空のインターフェイスは、Javaのマーカーインターフェイスと呼ばれます。
2.Serializemain.java
org.arpit.Javapostsforning; args){Employe emp = emp.setemployeename( "arpit"); ser ")); objectputStream outStream = new objectputStream(fileout); outStream.writeObject(emp); outStream.close();例外i){i.printstacktrace();}}}}}
バックのために - シーケンシャル化:
ステップはです
パッケージでsrc-> org.arpit.javapostsforlearningで、deserializemain.javaを作成します
3.Deserializemain.java
Package org.arpit.javapostsforning java.io.io.io.objectinputStream { / *** @aut hor arpit main(String){従業員emp = null {fileInputStremStream( "employe.ser") ioException i){i.printstacktrace(); ... "); system.out.println(" empid: " + emp.getemployeid()); system.out.println(" name: " + emp.getemployeename()); stem.out.println("部門: " + emp.getDeppartment());}}
4。実行:
最初にserializemain.javaを実行し、次にdeserializemain.javaを実行すると、次の結果が得られます。
Deserialized Emblayee ... Emp Id:101Name:arpitdepapartment:cs
このようにして、従業員のオブジェクトをシリアル化し、それを実行しました。これはシンプルに見えますが、オブジェクトの参照と継承が含まれている場合、状況は複雑になります。さまざまな機会にシリアル化を達成する方法を確認するために、例を1つずつ見てみましょう。
ケース1-オブジェクトが他のオブジェクトを引用している場合、私は何をすべきか
すでに最も単純なシーケンスベースの例を見てきました。どうすればシリアル化できますか?引用されたオブジェクトもシリアル化しますか?はい、明示的にシリアル化する必要はありません。オブジェクトが参照オブジェクトが含まれている場合、オブジェクトをシリアル化すると、Javaシリアル化はオブジェクトのオブジェクト図全体を自動的にシリアル化します。たとえば、従業員はアドレスオブジェクトを引用し、アドレスは他のオブジェクト(ホームなど)を引用し、従業員オブジェクトをシリアル化すると、住所やホームなどの他のすべてのオブジェクトがシリアル化によって自動的にシリアル化されますアドレスクラスを作成し、アドレスのオブジェクトを参照として追加して、従業員クラスに追加します。
従業員。Java:
Package.javapostsforning java.io.serializable this.employeeid = employeeId;} public string getemployeename(){return employeeename;} public void setempoloyeename(string employeename){this.emplayeename = employeeName;} public string getdeppartment(){return department;} public boid setdeppartment(String Department){String Department) this.department = department;} public address getaddress(){return address;} public void address(addressアドレス){this.address =アドレス}}
org.arpit.javapostsforlerningパッケージで、address.javaを作成します
address.java:
Package arpit.javapostsforning {int homeno、super this .city = city;} public int gethomeno(){return homeno;} public void sethomeno(int home){this.homeno = homeno;} public stringstreet(){Street;} public void setStreet(String Street){this。 Street = Street;} public String getCity(){return City;} public void setCity(String City){this.city = city;}}
org.arpit.javapostsforlerningで、SerializeSearializemain.javaを作成します
SerializeSerializemain.java:
org.java.io.io.io.io.ioxception; Mandliya */ Public void main(] emply() 88、「Mg Road」、「Pune」) close();} catch(ioexception i){i.printstacktrace(); (従業員)in.close();脱必要な従業員... "); system .out.println(" empid: " + emp.getemployeid()); system.out.println(" name: " + emp.getemployeename()); mp.getDepartment() )address = emp.getAddress();
実行:
SerializeSeSerializemain.javaを実行するとき。あなたはそのような結果を得るでしょう:
java.Io.notserializableException: Org.arpit.javapostsforning.address at Java.io.objectPuttream.writeObject0 (UNKNOWN SOURCE) at Java.i O.ObjectPutstream.defaultWriteFields (Unknown Source) at java.io.objectPuttream.writeSerialData (UNKNOWN SOURCE) java.io.objectputstream.writeordinaryobject(不明なソース)java.io.objecttream.writeobject0(unknown source)at java.io.ob.ob jectoutputstream.writeobject(不明なソース)の
それがどこで間違っているかを説明します。アドレスクラスもシリアル化可能でなければならないと言うのを忘れました。その後、アドレスクラスはシリアルズーブルインターフェイスを継承する必要があります。
address.java:
java.io.serializable {int homeno、string t、super(); .city = city;} public int gethomeno(){return homeno;} public void sethomeno(int homeno){this.homeno = homeno = homeno;} public stringstreet()return Street;} public void setStreet(String Street){This this this this this .street = Street;} public String getCity(){return City;} public void setCity(String City){this.city = City;}}}}
もう一度実行:
再び実行すると、SerializeSeerializemain.javaを実行します。次の結果を得ることができます
Deserialized Emblayee ... Emp Id:101Name:arpitdepartment:cscity:pune
ケース2:参照オブジェクトのソースコードにアクセスできない場合(たとえば、上記のアドレスクラスのソースコードにアクセスできません)
アドレスクラスにアクセスできない場合、アドレスクラスにシリアル化可能なインターフェイスをどのように実装できますか?それを達成する別の方法はありますか?はい、別のクラスを作成し、アドレスを継承してから、シリアル化可能なインターフェイスを継承させますが、次の状況では、このソリューションは失敗します。
参照クラスがファイナルとして定義されている場合
参照クラスが別の非シリアル化オブジェクトを参照する場合
では、従業員オブジェクトをどのようにシリアル化できますか?解決策は、遷移をマークすることです。フィールドをシリアル化する必要がない場合は、一時的なものとしてマークするだけです。
一時的なアドレスアドレス
従業員クラスでは、アドレスが一時的なものとしてマークされた後、プログラムを実行します。 Deeperyのプロセス中にアドレス参照がヌルになるため、NullPointerExceptionを取得します。
ケース3-参照オブジェクトの状態を保存する必要がある場合はどうなりますか? (たとえば、アドレスオブジェクト)
Deepertineのプロセス中にアドレスを一時的にマークした場合、NULLの結果が返されます。ただし、状態を保存する必要がある場合は、アドレスオブジェクトをシリアル化する必要があります。 Javaのシリアル化は、特定の署名プライベートメソッドを提供する場合、シリアル化中に呼び出されます。
従業員。Java:
org.java.io.io.io.objecttream.serializable;住所; employeed( ; OS)IOException、classNotFoundException {os.DefaultWriteObject(); ;}} private void object(objectinputStream)は、exception {is.defaultreadobject()int homeno = is.readint(); .ReadObject();アドレス(Homeno、Street、City);}
もう1つのことは、ObjectInputStreamがObjectOutputStreamのデータの順序を読み取ります。
address.javaを作成します
address.java:
Package.arpit.java.io.serializable {int homeno、string city; = Street; this.city = city;} public int gethomeno(){return homeno;} public void sethomeno(int homeno){this.homeno = public string getStreet(){return Street;} this.street = street;} public string getCity(){return city;} public void setCity(String City){this.city = City;
SerializeSerializemain.javaを作成します
SerializeSerializemain.java:
org.java.io.io.io.io.ioxception; Mandliya */ Public void main(] emply() 88、「Mg Road」、「Pune」) close();} catch(ioexception i){i.printstacktrace(); (従業員)in.close();脱必要な従業員... "); system .out.println(" empid: " + emp.getemployeid()); system.out.println(" name: " + emp.getemployeename()); mp.getDepartment() )address = emp.getAddress();
走る:
SerializeSeRializemain.javaを実行すると、次の結果が得られます。
Deserialized Emblayee ... Emp Id:101Name:arpitdepartment:cscity:pune
これで、アドレスオブジェクトの状態を取得します。
シリアル化の継承:
それでは、継承がシリアル化にどのように影響するかを見てみましょう。親クラスがシリアル化されているかどうかに関係なく、これは多くの例につながります。親クラスがシリアル化されていない場合、私たちは何をし、それがどのように機能するか。例を見てみましょう。
従業員の親クラスとしてperson.javaを作成します。
ケース4:親クラスがシリアル化されている場合
親クラスがシリアル化できる場合、すべての継承クラスはシリアル化されます。
ケース5:親クラスがシリアル化されていない場合はどうなりますか?
親クラスが非主目化されていない場合、処理方法は非常に異なります。
親クラスが非シリアル化されている場合、パラメーターコンストラクター関数を持たないはずです。
person.java
Package org.arpit.javapostsforning; super(); this.name = neationality = nationality;} public name;} public void setname(string name){this .name = name;} ;} public void setNationality(String Nationality){this.nationality =国籍;}}
employee.javaを作成します
従業員。Java:
org.arpit.javapostsforning 。部門;} public void setDeppartment(String Department){this.deppartment = department;}}}
SerializeSerializemain.javaを作成します
SerializeSerializemain.java:
org.java.io.io.io.io.ioxception; mandliya */public static void main(String [] args){// serialize empt = new Employee( "arpit"、 "Indian"); .println( "empid:" + emp.getemployeid()); getDeppartment()); )outStream.writeObject(); *********** "););; try {fileInputStream filein = new fileInputStream(" Employeinge.ser ");)in.ReadObject(); in.close(); filein.close() ;} catch(IoExceptrace();} catch(system.out.println) ( "After serializing"); "部門:" + emp.getDeppartment());
走る:
SerializeSeRializemain.javaを実行すると、親クラスが継承されるすべてのインスタンス値が関数と呼ばれます。 ここでは、名前は直接継承されているため、Deeperyのプロセス中に、名前はデフォルト値に初期化されます。
ケース6-親クラスがシリアル化されているが、シリアル化としてクラスを継承する必要はない場合
クラスをシリアル化して継承したくない場合は、writeObject()およびreadObject()メソッドを実装し、NotserializableExceptionの異常を捨てる必要があります。
ケース7-静的変数はシリアル化できますか?
できません。静的変数はオブジェクトレベルではなくクラスレベルであるため、静的変数をシリアル化することはできません。
要約: