シーケンス化07:シーケンス化エージェント
7011 ワード
シーケンス化エージェントは簡単に言えば、Aにはシーケンス化の需要があるが、直接Aをシーケンス化するのではなく、Aをシーケンス化するエージェントBであり、Aの情報をBに保存することができ、逆シーケンス化時にBを通じてAの情報を得て、Aオブジェクトをインスタンス化するのになぜこんなに苦労するのか.逆シーケンス化はjavaメカニズム以外のものなので、構築方法でインスタンスを生成しないので、このように侵入される機会があり(具体的には黒になる可能性があるという意味でしょう)、シーケンス化エージェントを採用することで、逆シーケンス化によるインスタンスの生成を効果的に回避することができ、すべてのインスタンスがコンストラクション関数によって生成され、すべてのインスタンスがコンストラクション関数の制約を遵守することを保証することができます.具体的には、例によって説明しましょう.
内部クラスが定義されており、SerializationProxyはDogのシーケンス化エージェントとしてDogをシーケンス化しようとすると、Dogで定義されているため
実際にはDogのシーケンス化エージェントがシーケンス化され、このシーケンス化エージェントはDogオブジェクトによって構築される(Dogの情報が保存されている).前節では、以降のプロセスは実際にシーケンス化されたクラスのシーケンス化実装、すなわちDogシーケンス化された世代のシーケンス化実装に依存し、Dogシーケンス化されたエージェントを逆シーケンス化する場合、
実際にはDogオブジェクトが返され、元のDog情報が戻ってきます.新しいDogインスタンスは構造方法で生成されます.
どのように使うのか、実は全く見えないので、普通に使えばいいのです
使い方は同じで、重要なのはシーケンス化クラスwirteObjectとreadObjectの実現です.
public class Dog implements Serializable {
/** * */
private static final long serialVersionUID = 2599175554577989702L;
private String name;
private int age;
Dog(String name,int age)
{
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private static class SerializationProxy implements Serializable {
/** * */
private static final long serialVersionUID = -1792022185138959673L;
private String name;
private int age;
SerializationProxy(Dog dog)
{
this.name = dog.name;
this.age = dog.age;
}
private Object readResolve()
{
return new Dog(name,age);
}
private void writeObject(ObjectOutputStream out) throws IOException
{
out.defaultWriteObject();
System.out.println(" ");
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
in.defaultReadObject();
System.out.println(" ");
}
}
private Object writeReplace()
{
return new SerializationProxy(this);
}
private void readObject(ObjectInputStream in) throws Exception
{
throw new Exception("proxy required");
}
}
内部クラスが定義されており、SerializationProxyはDogのシーケンス化エージェントとしてDogをシーケンス化しようとすると、Dogで定義されているため
private Object writeReplace()
{
return new SerializationProxy(this);
}
実際にはDogのシーケンス化エージェントがシーケンス化され、このシーケンス化エージェントはDogオブジェクトによって構築される(Dogの情報が保存されている).前節では、以降のプロセスは実際にシーケンス化されたクラスのシーケンス化実装、すなわちDogシーケンス化された世代のシーケンス化実装に依存し、Dogシーケンス化されたエージェントを逆シーケンス化する場合、
private Object readResolve()
{
return new Dog(name,age);
}
実際にはDogオブジェクトが返され、元のDog情報が戻ってきます.新しいDogインスタンスは構造方法で生成されます.
どのように使うのか、実は全く見えないので、普通に使えばいいのです
@Test
public void testOut03() throws FileNotFoundException, IOException
{
Dog d = new Dog(" ",2);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:\\temp01.txt"));
out.writeObject(d);
out.flush();
out.close();
}
@Test
public void testIn03() throws FileNotFoundException, IOException, ClassNotFoundException
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:\\temp01.txt"));
Dog d = (Dog)in.readObject();
in.close();
System.out.println(d.getAge());
System.out.println(d.getName());
}
}
使い方は同じで、重要なのはシーケンス化クラスwirteObjectとreadObjectの実現です.