Сериализация и десериализация объектов
Сериализация — это процесс преобразования объекта в последовательность байтов, которая может быть сохранена в файл или передана по сети.
Десериализация — это обратный процесс, при котором байты преобразуются обратно в объект. Эти процессы позволяют сохранять состояние объекта и восстанавливать его в любой момент.
Сериализация
Для того чтобы объект можно было сериализовать, его класс должен реализовывать интерфейс Serializable. Этот интерфейс является маркерным, то есть не содержит методов и служит лишь для указания JVM, что объекты этого класса могут быть сериализованы.
Пример класса, реализующего Serializable:
В этом примере класс Person реализует Serializable, что позволяет его объекты сериализовать.
Процесс сериализации:
Создаем объект ObjectOutputStream, связанный с выходным потоком (например, FileOutputStream).
Вызываем метод writeObject(Object obj) для записи объекта в поток.
Пример сериализации:
Десериализация
Процесс десериализации включает чтение последовательности байтов и создание из них объекта. Для этого используется класс ObjectInputStream.
Процесс десериализации:
Создаем объект ObjectInputStream, связанный с входным потоком (например, FileInputStream).
Вызываем метод readObject() для чтения объекта из потока. Обязательно выполняем приведение типа (casting) к нужному классу.
Пример десериализации:
serialVersionUID
Каждый сериализуемый класс должен иметь статическое поле serialVersionUID, которое используется для обеспечения совместимости версий класса. Если serialVersionUID у класса изменится, десериализация объектов, сериализованных с предыдущей версией класса, вызовет ошибку.
Пример объявления serialVersionUID:
Транзиентные поля
Поля, помеченные ключевым словом transient, не будут сериализованы. Это полезно для полей, которые не нужно сохранять, например, паролей или других конфиденциальных данных.
Пример использования transient:
В этом примере поле password не будет сериализовано.
#Java #Training #IO #Serializable
Сериализация — это процесс преобразования объекта в последовательность байтов, которая может быть сохранена в файл или передана по сети.
Десериализация — это обратный процесс, при котором байты преобразуются обратно в объект. Эти процессы позволяют сохранять состояние объекта и восстанавливать его в любой момент.
Сериализация
Для того чтобы объект можно было сериализовать, его класс должен реализовывать интерфейс Serializable. Этот интерфейс является маркерным, то есть не содержит методов и служит лишь для указания JVM, что объекты этого класса могут быть сериализованы.
Пример класса, реализующего Serializable:
import java.io.Serializable;
class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
В этом примере класс Person реализует Serializable, что позволяет его объекты сериализовать.
Процесс сериализации:
Создаем объект ObjectOutputStream, связанный с выходным потоком (например, FileOutputStream).
Вызываем метод writeObject(Object obj) для записи объекта в поток.
Пример сериализации:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializationExample {
public static void main(String[] args) {
Person person = new Person("John Doe", 30);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
oos.writeObject(person);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Десериализация
Процесс десериализации включает чтение последовательности байтов и создание из них объекта. Для этого используется класс ObjectInputStream.
Процесс десериализации:
Создаем объект ObjectInputStream, связанный с входным потоком (например, FileInputStream).
Вызываем метод readObject() для чтения объекта из потока. Обязательно выполняем приведение типа (casting) к нужному классу.
Пример десериализации:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class DeserializationExample {
public static void main(String[] args) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
Person person = (Person) ois.readObject();
System.out.println(person);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
serialVersionUID
Каждый сериализуемый класс должен иметь статическое поле serialVersionUID, которое используется для обеспечения совместимости версий класса. Если serialVersionUID у класса изменится, десериализация объектов, сериализованных с предыдущей версией класса, вызовет ошибку.
Пример объявления serialVersionUID:
class Person implements Serializable {
private static final long serialVersionUID = 1L;
// остальные поля и методы
}Транзиентные поля
Поля, помеченные ключевым словом transient, не будут сериализованы. Это полезно для полей, которые не нужно сохранять, например, паролей или других конфиденциальных данных.
Пример использования transient:
class User implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private transient String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
@Override
public String toString() {
return "User{username='" + username + "', password='" + password + "'}";
}
}В этом примере поле password не будет сериализовано.
#Java #Training #IO #Serializable
Раздел 11. Работа с файлами, I/O и сетью (NIO.2)
Глава 3. Сериализация и форматы обмена
Нативная сериализация Java: интерфейс Serializable
Интерфейс
Он не требует реализации методов, не содержит констант и не накладывает контрактов на поведение класса. Его единственное назначение — сигнализировать JVM и стандартной библиотеке, что экземпляры данного класса разрешено преобразовывать в поток байтов и восстанавливать из него.
Этот механизм глубоко интегрирован в JVM: он обходит граф объектов, записывает метаданные классов, управляет версионностью и обеспечивает восстановление ссылочной целостности. Однако за простотой использования скрывается сложная внутренняя архитектура, множество подводных камней и серьёзные ограничения, которые делают нативную сериализацию устаревшим выбором для новых систем.
Маркерный интерфейс Serializable
Маркерный интерфейс — это интерфейс в Java без методов и полей, служащий метаданным для компилятора или runtime.
При попытке сериализовать объект, класс которого не реализует
Если
#Java #для_новичков #beginner #IO #NIO #Serialize #Serializable
Глава 3. Сериализация и форматы обмена
Нативная сериализация Java: интерфейс Serializable
Интерфейс
java.io.Serializable — это центральный элемент механизма нативной сериализации Java, существующий с версии JDK 1.1.Он не требует реализации методов, не содержит констант и не накладывает контрактов на поведение класса. Его единственное назначение — сигнализировать JVM и стандартной библиотеке, что экземпляры данного класса разрешено преобразовывать в поток байтов и восстанавливать из него.
Этот механизм глубоко интегрирован в JVM: он обходит граф объектов, записывает метаданные классов, управляет версионностью и обеспечивает восстановление ссылочной целостности. Однако за простотой использования скрывается сложная внутренняя архитектура, множество подводных камней и серьёзные ограничения, которые делают нативную сериализацию устаревшим выбором для новых систем.
Маркерный интерфейс Serializable
Serializable — это маркерный интерфейс (marker interface). В отличие от обычных интерфейсов, он не объявляет ни одного метода. Его роль чисто декларативная: наличие implements Serializable в объявлении класса изменяет поведение JVM при обработке этого класса механизмом сериализации.import java.io.Serializable;
public class Document implements Serializable {
// Маркерный интерфейс не требует методов
private String title;
private String content;
}
Маркерный интерфейс — это интерфейс в Java без методов и полей, служащий метаданным для компилятора или runtime.
Cloneable, Serializable, RandomAccess — примеры таких интерфейсов. Они не влияют на структуру класса напрямую, но изменяют поведение встроенных механизмов JVM. В современной Java роль маркерных интерфейсов частично вытесняется аннотациями (например, @Entity в JPA), но Serializable остаётся неизменным с 1997 года по причинам обратной совместимости.Аннотация (annotation) — это форма метаданных в Java, введённая в Java 5, которая предоставляет данные о программе, не являющиеся частью самой программы. Аннотации не влияют непосредственно на операции кода, но могут обрабатываться компилятором, инструментами или во время выполнения через рефлексию.
При попытке сериализовать объект, класс которого не реализует
Serializable, ObjectOutputStream.writeObject() выбросит NotSerializableException. Это проверка выполняется рекурсивно: если класс реализует Serializable, но одно из его полей — объект класса без Serializable, исключение возникнет при попытке записать это поле.public class Container implements Serializable {
private Document doc; // Document должен быть Serializable
private Metadata meta; // Metadata тоже должен быть Serializable
}Если
Metadata не реализует Serializable, сериализация Container завершится NotSerializableException на этапе обхода поля meta. Это ограничение каскадируется по всему графу объектов: каждый объект, достижимый от корневого, должен быть сериализуемым, либо должен быть помечен как transient.#Java #для_новичков #beginner #IO #NIO #Serialize #Serializable
👍4