"Olá, amigo! Hoje aprenderemos sobre outro tópico interessante. Especificamente, salvando e carregando (reconstruindo) objetos . Suponha que temos uma classe Cat:"

Código
class Cat
{
 public String name;
 public int age;
 public int weight;
}

E digamos que queremos adicionar um mecanismo conveniente para salvar e carregar de um arquivo.

Poderíamos fazer assim:

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

"Uau! Isso é tão fácil! Nós apenas escrevemos os valores de cada argumento, um em cada linha. Quando carregamos o arquivo, nós os lemos na mesma ordem. É a solução perfeita."

"Obrigado, amigo. Agora você pode escrever os métodos save e load para este grupo de classes:"

Código
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;
}

Você tem um objeto Humano, que pode ter um cachorro e um gato.

"Eu tenho uma solução:"

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

"Essa é uma solução muito boa. Mas o que acontece se um humano tiver um cachorro, mas não um gato?"

Onde estão os cheques nulos?

"Vou consertar agora:"

Código
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);
    }
}

"Ainda não está certo. Você tem dois erros:"

1) Uma pessoa pode não ter um gato ou cachorro, mas eles ainda serão criados quando o método load for chamado

2) Se salvarmos apenas um cachorro, seus dados serão lidos pelo gato quando ele for carregado.

"Bem, o que devo fazer?"

" Não podemos pular a gravação das variáveis, caso contrário teremos problemas durante a leitura . Você precisa garantir que as variáveis ​​que são nulas durante a operação de salvamento sejam definidas como nulas durante a operação de carregamento. Aqui está minha versão:"

Código
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);
        }
    }
}

"Sim, eu gosto desta solução."

"Sim, é bom."