「こんにちは、アミーゴ! 今日は別の興味深いトピックについて学びます。具体的には、オブジェクトの保存と読み込み(再構築)です。Cat クラスがあるとします。」

コード
class Cat
{
 public String name;
 public int age;
 public int weight;
}

そして、ファイルへの保存とファイルからのロードのための便利なメカニズムを追加したいとします。

次のようにすることができます:

コード
class Cat {
    public String name;
    public int age;
    public int weight;

    public void save(PrintWriter writer) throws Exception {
        writer.println(name);
        writer.println(age);
        writer.println(weight);
        writer.flush();
    }

    public void load(BufferedReader reader) throws Exception {
        name = reader.readLine();
        age = Integer.parseInt(reader.readLine());
        weight = Integer.parseInt(reader.readLine());
    }
}

「わお! とても簡単ですね! 各引数の値を各行に 1 つずつ記述するだけです。ファイルをロードするときに、同じ順序でそれらを読み取ります。これは完璧なソリューションです。」

「ありがとう、アミーゴ。これで、このクラス グループの保存メソッドと読み込みメソッドを作成できます。」

コード
class Cat
{
 public String name;
 public int age;
 public int weight;
}
class Dog
{
 public String name;
 public int age;
}
class Human
{
 public Cat cat;
 public Dog dog;
}

犬と猫を 1 匹ずつ飼うことができる Human オブジェクトがあります。

「解決策があります。」

コード
class Cat {
    public String name;
    public int age;
    public int weight;

    public void save(PrintWriter writer) throws Exception {
        writer.println(name);
        writer.println(age);
        writer.println(weight);
        writer.flush();
    }

    public void load(BufferedReader reader) throws Exception {
        name = reader.readLine();
        age = Integer.parseInt(reader.readLine());
        weight = Integer.parseInt(reader.readLine());
    }
}
コード
class Dog {
    public String name;
    public int age;

    public void save(PrintWriter writer) throws Exception {
        writer.println(name);
        writer.println(age);
        writer.flush();
    }

    public void load(BufferedReader reader) throws Exception {
        name = reader.readLine();
        age = Integer.parseInt(reader.readLine());
    }
}
コード
public class Human {
    public Cat cat;
    public Dog dog;

    public void save(PrintWriter writer) throws Exception {
        cat.save(writer);
        dog.save(writer);
    }

    public void load(BufferedReader reader) throws Exception {
        cat.load(reader);
        dog.load(reader);
    }
}

「それは非常に良い解決策です。しかし、人間が犬を飼っていて猫を飼っていない場合はどうなるでしょうか?」

null チェックはどこにありますか?

「今すぐ修正します:」

コード
public class Human {
    public Cat cat;
    public Dog dog;

    public void save(PrintWriter writer) throws Exception {
        if (cat != null)
            cat.save(writer);
        if (dog != null)
            dog.save(writer);
    }

    public void load(BufferedReader reader) throws Exception {
        cat = new Cat();
        cat.load(reader);
        dog = new Dog();
        dog.load(reader);
    }
}

「まだ完全に正しくありません。2 つの間違いがあります。」

1)人は猫や犬を飼っていないかもしれませんが、load メソッドが呼び出されたときに猫や犬が作成されます。

2)犬のみを保存した場合、そのデータはロード時に猫によって読み取られます。

「さて、どうすればいいでしょうか?」

変数の書き込みを省略することはできません。そうしないと、読み取り中に問題が発生します。保存操作中に null である変数が、読み込み操作中に null に設定されていることを確認する必要があります。これが私のバージョンです。」

コード
public class Human {
    public Cat cat;
    public Dog dog;

    public void save(PrintWriter writer) throws Exception {
        String isCatPresent = cat != null ? "yes" : "no";
        writer.println(isCatPresent);
        writer.flush();

        if (cat != null)
            cat.save(writer);

        String isDogPresent = dog != null ? "yes" : "no";
        writer.println(isDogPresent);
        writer.flush();

        if (dog != null)
            dog.save(writer);
    }

    public void load(BufferedReader reader) throws Exception {

        String isCatPresent = reader.readLine();
        if (isCatPresent.equals("yes")) {
            cat = new Cat();
            cat.load(reader);
        }

        String isDogPresent = reader.readLine();
        if (isDogPresent.equals("yes")) {
            dog = new Dog();
            dog.load(reader);
        }
    }
}

「はい、この解決策が気に入っています。」

「はい、いいですね。」