Руководство по Java Core. Сериализация.

Язык программирования Java поддерживает механизм, который может представить объект в виде последовательности байтов. Эта последовательность содержит информацию как сам объект, так и информацию о типе объекта и типах данных, которые хранятся в этом объекте.

Такой механизм называется сериализация.

После того как сериализованный объект записан в виде файла, он может быть прочитан из файла и десериализован, то есть, восстановлен из памяти.

Наиболее важным моментом является то, что этот процесс не зависит от JVM, т.е. объект может быть сериализован на одной платформе, а десериализован (полностью воспроизведён) на абсолютно другой.

Такие классы, как ObjectInputStream и ObjectOutputStream, являются потоками, которые содержат методы для сериализации и десериализации объектов.

Для того чтобы класс мог быть сериализован, должны быть соблюдены определённые условия:

  • Класс должен имплементировать интерфейс java.io.Serializable
  • Все поля класса должны быть сериализованы. Поля, которые мы хотим исключить, должны быть отмечены, как transient.

Для понимания того, как это работает на практике, рассмотрим пример простого приложения, в котором мы попробуем сериализовать, а затем – десериализовать класс Developer, который содержит информацию о разработчике.

Пример:

Класс Developer


import java.io.Serializable;

public class Developer implements Serializable {
    private String name;
    private String specialty;
    private int experience;
    transient private int salary;

    public Developer(String name, String specialty, int experience, int salary) {
        this.name = name;
        this.specialty = specialty;
        this.experience = experience;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSpecialty() {
        return specialty;
    }

    public void setSpecialty(String specialty) {
        this.specialty = specialty;
    }

    public int getExperience() {
        return experience;
    }

    public void setExperience(int experience) {
        this.experience = experience;
    }

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public void doJob() {
        System.out.println(this.specialty + " developer " + this.name + " is writing code...");
    }

    @Override
    public String toString() {
        return "Developer:" +
                "\nName: " + name +
                "\nSpecialty: " + specialty +
                "\nExperience: " + experience +
                "\nSalary: " + salary + "\n";
    }
}

Класс SerializationDemo


import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class SerializationDemo {
    public static void main(String[] args) throws IOException {
        Developer developer = new Developer("Proselyte", "Java", 3, 2000);

        FileOutputStream fileOutputStream =
                new FileOutputStream("resources/Developer.info");
        ObjectOutputStream outputStream =
                new ObjectOutputStream(fileOutputStream);

        outputStream.writeObject(developer);
        outputStream.close();
        fileOutputStream.close();

        System.out.println("Developer serialized successfully.");
    }
}

В результате работы программы, которая сериализирует объект, мы получим, примерно следующий результат:


/*Some System Messages*/

Developer serialized successfully.

Класс DeserializationDemo


import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class DeserializationDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Developer developer = null;

        FileInputStream fileInputStream =
                new FileInputStream("resources/Developer.info");
        ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);

        developer = (Developer) inputStream.readObject();
        inputStream.close();
        fileInputStream.close();

        System.out.println("Deserializing... Developer:");
        System.out.println(developer);
    }
}

В результате работы программы, которая десериализирует объект, мы получим, примерно следующий результат:


/*Some System Messages*/

Deserializing... Developer:
Developer:
Name: Proselyte
Specialty: Java
Experience: 3
Salary: 0

Как мы видим, все поля класса, кроме salary (зарплаты) были сериализованы и десериализованы. Поле salary получило значение по умолчанию для своего типа данных (для типа данных int это 0).

В этом уроке мы изучили основы сериализации и рассмотрели примеры приложений, которые сериализуют и восстанавливают объект.

В следующем уроке мы начнём изучать многопоточность.