0

インスタンス変数として別のオブジェクトへの参照を持つオブジェクトをシリアライズしようとしています。私は一般的な方法に従いますが、main() メソッドで 2 番目のオブジェクト (シリアル化できない) を取得することはできません。ここに私のコードがあります:

 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();
    }
}

2 番目の try ブロックの「コメント」行で、nullPointerException がスローされます。この方法では Car オブジェクトを保存できません。乗り越えるにはどうしたらいいですか?もちろん、私は必ず Car クラスをシリアル化できないままにしておきたいと思っています。Car オブジェクトのインスタンス変数を保存し、それらとそのコンストラクターを使用して再作成したい場合、どのように 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() メソッドは存在しません。

4

1 に答える 1

0

この線

car = (Car)is.readObject();

間違っている。車はシリアル化できません。

ソリューション:

  1. 車をシリアライズ可能にし、行を削除します

  2. ser/deser の目的でのみシリアライズ可能な MyCar オブジェクトを使用し、MyCar から車を作成します。ポイント 3 を参照してください。

  3. 新しい車を作成します: car = new Car(); しかし、どこからデータを取得するのですか? (ポイント 2 を参照)

  4. os.writeObject() を使用して car のフィールドを 1 つずつ seialize し、os.writeInt(); などのプリミティブを使用します。

  5. DataOutputStream を使用して、独自のカスタム シリアル化を使用する

更新の質問に対する回答を更新する

String はオブジェクトです。os.writeObject(car.type); でシリアル化します。ソリューション 4 を使用した ObjectOutputStream コード
も参照してください。

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();
    }
}
于 2012-12-11T12:48:41.693 に答える