关于序列化,常又称为持久化,是将数据其写入磁盘中。
对于编码规则来说:任一一个实体类必须要去实现 Serializable接口,方便以后将该类持久化,或者将其用于转为字节数组,用于网络传输。对于一个实体类,不想将所有的属性都进行序列化,可以将部分属性声明为transient。
序列化整个过程都是Java虚拟机(JVM)独立的,也就是说,在一个平台上序列化的对象可以在另一个完全不同的平台上反序列化该对象。
类 ObjectInputStream 和 ObjectOutputStream 是高层次的数据流,它们包含反序列化和序列化对象的方法。
ObjectOutputStream 类包含很多写方法来写各种数据类型,但是一个特别的方法例外:
public final void writeObject(Object x) throws IOException
上面的方法序列化一个对象,并将它发送到输出流。相似的 ObjectInputStream 类包含如下反序列化一个对象的方法:
public final Object readObject() throws IOException,ClassNotFoundException
该方法从流中取出下一个对象,并将对象反序列化。它的返回值为Object,因此,需要将它转换成合适的数据类型。
下面定义一个可序列化的类:
class myClass implements java.io.Serializable {
public String name;
public String address;
public transient int age;
public transient String number;
public void fun1() {
System.out.println("你好");
}
}
说明:一个类的对象要想序列化成功,必须满足以下两个条件。
1.该类必须实现 java.io.Serializable 对象。
2.该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂的(transient)。
如果想知道一个Java标准类是否是可序列化的,只需要查看该类有没有实现 java.io.Serializable接口。
1.序列化对象
ObjectOutputStream类用来序列化一个对象
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
//系列化
public class JavaSerialize {
public static void main(String[] args) {
MyClass myclass = new MyClass();
myclass.name = "liu";
myclass.address = "中国";
myclass.age = 18;
myclass.number = "123456";
try {
FileOutputStream fileout = new FileOutputStream("/Users/liu/Documents/LMM/myclass.ser");
ObjectOutputStream output = new ObjectOutputStream(fileout);
output.writeObject(myclass);
output.close();
fileout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.反序列化对象
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
//系列化
public class JavaSerialize {
public static void main(String[] args) throws ClassNotFoundException {
MyClass myclass = new MyClass();
myclass.name = "liu";
myclass.address = "中国";
myclass.age = 18;
myclass.number = "123456";
try {
FileOutputStream fileout = new FileOutputStream("/Users/liumingming/Documents/LMM/myclass.ser");
ObjectOutputStream output = new ObjectOutputStream(fileout);
output.writeObject(myclass);
output.close();
fileout.close();
} catch (IOException e) {
e.printStackTrace();
}
MyClass newClass = null;
try {
FileInputStream filein = new FileInputStream("/Users/liumingming/Documents/LMM/myclass.ser");
ObjectInputStream in = new ObjectInputStream(filein);
newClass = (MyClass) in.readObject();
in.close();
filein.close();
} catch (IOException e) {
e.printStackTrace();
return;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}
System.out.println(newClass.name); //liu
System.out.println(newClass.address); //中国
System.out.println(newClass.age); //0
System.out.println(newClass.number); //null
}
}
class MyClass implements java.io.Serializable {
public String name;
public String address;
public transient int age;
public transient String number;
public void fun1() {
System.out.println("你好");
}
}
说明:readObject() 方法中的 try/catch代码块尝试捕获 ClassNotFoundException 异常。对于 JVM 可以反序列化对象,它必须是能够找到字节码的类。如果JVM在反序列化对象的过程中找不到该类,则抛出一个 ClassNotFoundException 异常。
另外,由于属性age和number被声明为transient,所以反序列时取出的值为0和null。