通过序列化检索对象

时间:2012-12-11 12:38:42

标签: java string object serialization

我试图将具有对另一个Object的引用的Object作为实例变量进行seriliaze。我遵循常用的方式,但是我无法在main()方法中检索第二个Object(非Serializable)。这是我的代码:

 public class Car {

String type;
int speed;

public Car(String s, int v){
    type = s;
    speed = v;
}

}

public class Employee implements Serializable {

String name;
int Id;
transient Car car;

public Employee(String s, int i, Car c){
    name = s;
    Id = i;
    car = c;
}

private void writeObject(ObjectOutputStream os){
    try {
        os.defaultWriteObject();
        os.writeObject(car);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void readObject(ObjectInputStream is){
    try {
        is.defaultReadObject();
        car = (Car)is.readObject();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

主要方法:

public static void main(String[] args) {

    Car c = new Car("noType", 100);
    Employee e = new Employee("Aris", 1, c);

    try {
        FileOutputStream fo = new FileOutputStream("save.txt");
        ObjectOutputStream out = new ObjectOutputStream(fo);
        out.writeObject(e);
        out.close();
    } catch (IOException e1) {
        e1.printStackTrace();
    }


    try {
        FileInputStream fi = new FileInputStream("save.txt");
        ObjectInputStream in = new ObjectInputStream(fi);
        Employee emp = (Employee) in.readObject();     // Comment
        System.out.println(emp.car.speed);
        in.close();
    }catch (ClassNotFoundException e1) {
        e1.printStackTrace();
    } 
    catch (IOException e1) {
        e1.printStackTrace();
    }
}

在第二个try块的“Comment”行中,它抛出一个nullPointerException。它不能以这种方式保存Car对象。我该怎么做才能克服它? Ofcource我希望Car类必须保持非seriliazable。如果更喜欢保存Car对象的instrance变量并借助它们及其构造函数重新创建它,我该如何保存(并检索)String属性?

更新

当尝试仅保存int实例变量时,它可以工作。相关方法是这次:

private void writeObject(ObjectOutputStream os){
    try {
        os.defaultWriteObject();
        os.writeInt(car.speed);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void readObject(ObjectInputStream is){
    try {
        is.defaultReadObject();
        car = new Car("theNew", is.readInt());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

但我的问题仍然是如何(或者如果)我可以保存整个对象。毕竟我没有设法保存和检索字符串。 WriteString(),ReadString()方法 不存在。

1 个答案:

答案 0 :(得分:0)

该行

car = (Car)is.readObject();

错了。 汽车不可序列化。

解决方案:

  1. 使汽车可序列化,并删除行

  2. 使用仅用于ser / deser的Serriteable的MyCar对象,并从MyCar创建汽车,参见第3点。

  3. 创建一个新车:car = new Car();但是从哪里获取数据? (见第2点)

  4. 使用os.writeObject()逐个显示汽车的字段,并使用原语,例如os.writeInt();

  5. 使用您自己的自定义序列化,使用DataOutputStream

  6. 更新回答您的更新问题

    String是一个对象,用os.writeObject(car.type)序列化它;
    另见ObjectOutputStream
    代码使用解决方案4:

    private void writeObject(ObjectOutputStream os){
        try {
            os.defaultWriteObject();
            os.writeObject(car.type);
            os.writeInt(car.speed);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    
    private void readObject(ObjectInputStream is){
        try {
            is.defaultReadObject();
            String type = (String) is.readObject();
            int speed = is.readInt();
            this.car = new Car(type, speed);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }