0
0

More than 1 year has passed since last update.

ObjectInputStreamでInstance をファイルに書き込む/Serializable

Last updated at Posted at 2023-02-04

Value2をObjectOutputStream#writeObject()でファイルに書き込む
Value2からValue1を参照しているので芋づる式にValue1も書き込まれる
書き込む対象のclassはimplements Serializableが必要

class Value1 implements Serializable {
    int price ;
    String name;
}
class Value2 implements Serializable {
    int price ;
    String name;
    Value1 val;
    @Override
    public String toString() {
        return "v2-name:"+name+" v2.price:"+price+
                "v1-name:" + val.name + "v1-price:" + val.price;
    }
}

public class Outer {
    public static void main(String[] args) {
        //writeObj();
        readObj();
    }
    static void readObj() {
        try {
            FileInputStream fis = new FileInputStream("c:\\dirtest\\sample.ser");
            ObjectInputStream ois = new ObjectInputStream(fis);
            try(ois) {
                Object o = ois.readObject();
                Value2 v2 = (Value2)o;
                System.out.println(v2);
            }
        } catch (IOException|ClassNotFoundException ex) {
            ex.printStackTrace();
        }
    }
    static void writeObj() {
        try {
            FileOutputStream fos = new FileOutputStream("c:\\dirtest\\sample.ser");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            Value1 v1 = new Value1();
            v1.name="v1x";
            v1.price=100;
            Value2 v2 = new Value2();
            v2.name="v2x";
            v2.price=200;            
            v2.val = v1;
            try(oos) {
                oos.writeObject(v2);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
v2-name:v2x v2.price:200v1-name:v1xv1-price:100

writeObj後にValue2のtoString()をいじったあと、readObjしたら
以下のInvalidClassException発生
Value2にSerialVersionUIDが振られていてclassいじるとversionが変わって
read/writeで違いがあるとclass情報が読みだせなくなる仕組み

java.io.InvalidClassException: com.mycompany.mavenproject1.Value2; local class incompatible: stream classdesc serialVersionUID = 7637657283063083089, local class serialVersionUID = -358236726962437359
	at java.base/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:689)
	at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2042)
	at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1892)
	at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2223)
	at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1709)
	at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:500)
	at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:458)
	at com.mycompany.mavenproject1.Outer.main(Outer.java:35)

custome serialize/deserializeを使うとこうなる
Value2#writeObject, readObject methodでserializa/deserialize
writeObjectに、private つけないと無視された

class Value1 implements Serializable {
    int price ;
    String name;
}
class Value2 implements Serializable {
    int price ;
    String name;
    Value1 val;
    private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
        System.out.println("read object");
        this.name = (String)is.readObject();
        this.price = (int)is.readObject();
//        this.val = (Value1)is.readObject();
    }
    private void writeObject(ObjectOutputStream os) throws IOException {
        System.out.println("write object");
        os.writeObject(this.name);
        os.writeObject(this.price);
//        os.writeObject(this.val);
    }
    @Override
    public String toString() {
        String ret = "v2-name:"+name+" v2.price:"+price;
        if(val!=null) {
            ret = ret + "v1-name:" + val.name + "v1-price:" + val.price;
        }
        return ret;
    }
}

public class Outer {
    public static void main(String[] args) {
        writeObj();
        readObj();
    }
    static void readObj() {
        try {
            FileInputStream fis = new FileInputStream("c:\\dirtest\\sample.ser");
            ObjectInputStream ois = new ObjectInputStream(fis);
            try(ois) {
                Object o = ois.readObject();
                Value2 v2 = (Value2)o;
                System.out.println(v2);
            }
        } catch (IOException|ClassNotFoundException ex) {
            ex.printStackTrace();
        }
    }
    static void writeObj() {
        try {
            FileOutputStream fos = new FileOutputStream("c:\\dirtest\\sample.ser");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            Value1 v1 = new Value1();
            v1.name="v1x";
            v1.price=100;
            Value2 v2 = new Value2();
            v2.name="v2x";
            v2.price=200;            
            v2.val = v1;
            try(oos) {
                oos.writeObject(v2);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
write object
read object
v2-name:v2x v2.price:200
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0