在Java中,如果我们需要把对象持久化到硬盘,或者在网络上传输,类必须实现Serializable接口,使用对象流的形式,把对象写入磁盘。
如果该类没实现Serializable接口,当调用ObjectOutputStream.writeObject的时候,JVM将会抛出java.io.NotSerializableException异常。
Java序列化有几个特征:
1.当序列化子类的时候,如果父类没有实现Serializable接口,则反序列化的时候,将调用父类的构造方法重新生成父类对象;
public class SerializableDemo {
public static void main(String[] args) {
write();
System.out.println("--------");
read();
}
static void write() {
Dog dog = new Dog();
dog.name = "Nelson";
dog.age = 13;
try {
FileOutputStream fos = new FileOutputStream("/data2/object.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(dog);
fos.close();
oos.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
static void read() {
Dog dog = null;
try {
FileInputStream fis = new FileInputStream("/data2/object.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
dog = (Dog) ois.readObject();
fis.close();
ois.close();
}
catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(dog.name + "," + dog.age);
}
}
class Animal {
String name;
int age;
public Animal() {
System.out.println("invoke Animal constructor");
this.name = "Monkey";
this.age = 100;
}
}
class Dog extends Animal implements Serializable {
public Dog() {
System.out.println("invoke Dog constructor");
}
}
输出:
invoke Animal constructor
invoke Dog constructor
--------
invoke Animal constructor
Monkey,100
2.如果父类实现了Serializable接口,则反序列化的时候,将复用父类对象,不会重新构造父类
class Animal implements Serializable {
String name;
int age;
public Animal() {
System.out.println("invoke Animal constructor");
this.name = "Monkey";
this.age = 100;
}
}
class Dog extends Animal implements Serializable {
public Dog() {
System.out.println("invoke Dog constructor");
}
}
输出:
invoke Animal constructor
invoke Dog constructor
--------
Nelson,13
3.如果父类已经实现了Serializable接口,则子类可以不用显式地实现Serializable接口
class Animal implements Serializable {
String name;
int age;
public Animal() {
System.out.println("invoke Animal constructor");
this.name = "Monkey";
this.age = 100;
}
}
class Dog extends Animal {
public Dog() {
System.out.println("invoke Dog constructor");
}
}
输出:
invoke Animal constructor
invoke Dog constructor
--------
Nelson,13
4.如果A类持有B类的引用(B不为空),当序列化A类的时候,B类必须实现Serializable接口,否则JVM将会抛出java.io.NotSerializableException异常
5.当如果某个属性不想序列化,则使用transient关键字标记,当JVM序列化的时候,遇到transient关键字的属性,则会跳过此属性
class Animal implements Serializable {
transient String name;
int age;
public Animal() {
System.out.println("invoke Animal constructor");
this.name = "Monkey";
this.age = 100;
}
}
class Dog extends Animal {
public Dog() {
System.out.println("invoke Dog constructor");
}
}
输出:
invoke Animal constructor
invoke Dog constructor
--------
null,13