概念:对象序列化,就是将一个对象转化为二进制的数据流;
方法:想要被序列化的对象,在定义该类时,必须实现Serializable接口,或者实现Externalizable接口;
对象序列化实质是把对象的属性进行序列化为二进制数据流,方法则不管;因为对象直接只有属性是有差异的;
Serializable接口把对象所有属性进行序列化,Externalizable接口则是可以选择性的将部分属性进行序列化,一般选用Serializable接口,比较简便。
例1:将一个Student类的对象序列化输出至文件中
首先定义Student类:
class Student implements Serializable{
private String name=null;
private int age=0;
public Student(String name,int age){
this.name = name;
this.age = age;
}
public String toString(){
return "Name: "+name+"; Age: "+age;
}
}
接着,就可以用ObjectOutputStream类对其对象进行输出:
public static void main(String args[]){
try{
File file = new File("D:"+File.separator+"ser.txt");//输出目标文件
OutputStream out = new FileOutputStream(file);//文件输出流
ObjectOutputStream oout = new ObjectOutputStream(out);//对象输出流
oout.writeObject(new Student("wangjxy",25));//输出对象
out.close();
oout.close();
}catch(Exception e){
e.printStackTrace();
}
}
至此,可以看见ser.txt中已经有二进制数据的存在,如图:
完成对象的序列化输出后,可以进行反序列化读入:
InputStream in = new FileInputStream(file);//文件输入流
ObjectInputStream oin = new ObjectInputStream(in);//对象输入流
Student stu = (Student)oin.readObject();//读取对象,并向下转换为Student对象
System.out.println(stu);//输出对象
in.close();
oin.close();
可以发现得到了之前定义的对象:
以上方法可以发现,所有属性都被序列化,如果只是想序列化一部分属性,一部分属性不序列化,可以选用Externalizable接口完成,但是较为麻烦,比较简便的还是应用Serializable接口+transient字段进行完成;被transient字段修饰的属性,将不会被序列化,例如以上的例子,声明name属性时为:
private transient String name=null;
则在对象序列化存入文件,再被反序列化取出后,名字部分为null,而不是之前定义的“wangjxy”,因为改属性不会被序列化。
最后,如果想要一次性序列化多个对象,而不是一个一个多次序列化的话,可以运用对象数组,因为数组也是引用类型,所以可以将数组名按照对象名直接进行传入void writeObject(Object obj)中,如:
Student stu[] = new Student[3];
//.........具体实例化..........
oout.writeObject(stu);
之后读取也用对象数组:
Student stu[] = (Student[])oin.readObject();