所有的项目开发一定都有序列化的概念存在。
序列化基本概念
对象序列化指的是:将内存中保存的对象变为二进制数据流的形式进行传输,或者是将其保存在文本中。但是并不意味着所有类的对象都可以被序列化,严格来讲,需要被序列化的类对象往往需要传输使用,同时这个类必须实现java.io.Serializable接口。但是这个接口并没有任何的方法定义,只是一个标识而已。
例:定义可以被序列化对象的类
class Person implements Serializable {
private String name;
private Integer age;
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String toString() {
return "Person [name= " + name + ", age= " + age + "]";
}
}
序列化对象时所需要保存的就是对象中的属性,所以默认情况下对象的属性将被转为二进制数据流存在。
序列化与反序列化操作
如果要想实现序列化与反序列化的对象操作,在java.io包中提供有两个处理类:ObjectOutputStream、ObjectInputStream
首先来观察这两个类的定义结构及其各自的构造方法
ObjectOutputStream类:
类的定义
public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants
构造方法
public ObjectOutputStream(OutputStream out) throws IOExection
普通方法
public final void writeObject(Object obj) throws IOExection
ObjectInputStream类:
类的定义
public class ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants
构造方法
public ObjectInputStream(InputStream in) throws IOExection
对象序列化ObjectOutputStream
对象反序列化ObjectInputStream
例:实现对象序列化
class Person implements Serializable {
private String name;
private Integer age;
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String toString() {
return "Person [name= " + name + ", age= " + age + "]";
}
}
public class Test {
public static final File FILE = new File("C:"+File.separator+"Users"+File.separator+"贵军"+
File.separator+"Desktop"+ File.separator+"hello.txt");
public static void main(String[] args) throws FileNotFoundException, IOException {
ser(new Person("zhangsan", 20));
}
public static void ser(Object obj) throws FileNotFoundException, IOException {
ObjectOutputStream objectOutputStream =
new ObjectOutputStream(new FileOutputStream(FILE));
objectOutputStream.writeObject(obj);
objectOutputStream.close();
}
}
运行结果,将Person类的对象转变为二进制数据流保存在指定路径的文件中
例:实现对象反序列化
只需要修改上面的ser(Object obj)方法为 dser()方法
public static void dser() throws FileNotFoundException, IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(FILE));
System.out.println(objectInputStream.readObject());
objectInputStream.close();
}
会将上面文件中序列化的Person对象的内容反序列化,输出为
transient关键字(理解)
实际上序列化的处理在java.io包里面有两类,Serializable是使用最多的序列化接口,这种操作采用自动化模式完成,也就是说默认情况下所有的属性都会被序列化下来。
还有一个Externalizable接口是需要用户自己动手来处理序列化,一般很少使用。
但是由于Serializable默认会将对象中所有属性进行序列化保存,如果现在某些属性不希望被保存了,那么就可以使用transient关键字。
例:使用transient
class Person implements Serializable {
private transient String name; //使用transient关键字,防止序列化
private Integer age;
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String toString() {
return "Person [name= " + name + ", age= " + age + "]";
}
}
public class Test {
public static final File FILE = new File("C:"+File.separator+"Users"+File.separator+"贵军"+
File.separator+"Desktop"+ File.separator+"hello.txt");
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
ser(new Person("zhangsan", 20)); //序列化操作
dser(); //反序列化
}
public static void ser(Object obj) throws FileNotFoundException, IOException {
ObjectOutputStream objectOutputStream =
new ObjectOutputStream(new FileOutputStream(FILE));
objectOutputStream.writeObject(obj);
objectOutputStream.close();
}
public static void dser() throws FileNotFoundException, IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(FILE));
System.out.println(objectInputStream.readObject());
objectInputStream.close();
}
}
将Person对象中name属性使用transient修饰,则属性name不会进行序列化保存,因此序列化出的内容明显比上面例子中少
然后反序列化,可以看见属性name的值并没有保存,得到的是String类的缺省值
大部分情况下使用序列化往往是在简单java类上,其他类上使用序列化的操作模式相对较少。而如果是简单java类,很少去使用transient关键字了。