Бесплатный курс по Java: от основ до продвинутого уровня
Transient в Java
Как уже было сказано, при сериализации все поля сериализуемого объекта должны быть тоже Serializable.
Если какое-то поле сериализуемого объекта не Serializable и у нас нет доступа к нему для изменения (то есть мы не можем изменить какой-нибудь сторонний реализованный класс и добавить к нему implements Serializable), то можно просто это конкретное поле не сериализоватьобъявив его transient. Тогда будут сериализованы все поля объекта кроме transient поля и это поле будет null при десериализации.
Пример класса который не возможно сделать Serializable:
import java.io.*;
import java.util.*;
// Представим что у нас нет доступа
// к классу SomeNotSerializableClass
// для его изменения, он где-то в другом месте
// и поэтому мы не можем
// дописать ему implements Serializable.
// Но нам нужно сериализовать
// обьект класса Person приведенного ниже
// не смотря на то что в нем есть
// поле класса SomeNotSerializableClass
// который не Serializable
class SomeNotSerializableClass {
private int someField;
SomeNotSerializableClass(int a){
someField=a;
}
int getSomeField(){ return someField;}
}
Пример класса который будет сериализоваться/десериализоваться:
import java.io.*;
import java.util.*;
// это класс будем сериализовать/десериализовать
class Person implements Serializable{
private String name;
private int age;
private double height;
private boolean married;
// поле var ниже это поле класса о котором
// мы говорили выше, который не Serializable.
// Тогда можем просто не сериализовать его
// обьявив его transient, и в сериализованом обьекте
// класса Person поле var будет null.
private transient SomeNotSerializableClass var;
Person(String n, int a, double h, boolean m,
SomeNotSerializableClass var){
name=n; age=a; height=h; married=m; this.var=var;
}
String getName() {return name;}
int getAge() { return age;}
double getHeight(){return height;}
boolean getMarried(){return married;}
SomeNotSerializableClass getNotSerializable(){return var;}
}
public class TransientField {
public static void main(String[] args) {
// здесь обычная сериализация/десериализация
// сериализация
try(ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream(“person.dat”)))
{
Person p = new Person(“Sam”, 33, 178, true,
new SomeNotSerializableClass(20));
oos.writeObject(p);
}
catch(Exception ex){
System.out.println(ex.getMessage());
}
// десериализация
try(ObjectInputStream ois =
new ObjectInputStream(new FileInputStream(“person.dat”)))
{
Person p=(Person)ois.readObject();
System.out.printf(
“Name: %s \t Age: %d \t Height: %f \t Married: %b \t “,
p.getName(), p.getAge(), p.getHeight(),
p.getMarried());
System.out.print(“NotSerializableVariable: “);
System.out.print(p.getNotSerializable().getSomeField());
}
catch(Exception ex){
System.out.println(ex.getMessage());
}
}
}
Вывод:
Как видим, объект был сериализован частично. Поле, которое не Serealizable пустое, то есть null.