赞
踩
一、什么是序列化?
序列化的定义是:将一个对象编码成一个字节流(I/O);而与之相反的操作被称为反序列化。
序列化的目的是为了方便数据的传递以及存储到磁盘上(把一个Java对象写入到硬盘或者传输到网路上面的其它计算机,这时我们就需要将对象转换成字节流才能进行网络传输。对于这种通用的操作,就出现了序列化来统一这些格式)。
简单来说序列化就是一种用来处理对象流的机制。将对象转化成字节序列后可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。
- public class User1 implements Serializable {
-
- private String name;
- private int age;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
-
- @Override
- public String toString() {
- return "User{" +
- "name='" + name + '\'' +
- ", age=" + age +
- '}';
- }
- }
- public class SerializableDemo1 {
-
- public static void main(String[] args) {
- //Initializes The Object
- User1 user = new User1();
- user.setName("hollis");
- user.setAge(23);
- System.out.println(user);
-
- //Write Obj to File
- ObjectOutputStream oos = null;
- try {
- oos = new ObjectOutputStream(new FileOutputStream("tempFile"));
- oos.writeObject(user);
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- IOUtils.closeQuietly(oos);
- }
-
- //Read Obj from File
- File file = new File("tempFile");
- ObjectInputStream ois = null;
- try {
- ois = new ObjectInputStream(new FileInputStream(file));
- User1 newUser = (User1) ois.readObject();
- System.out.println(newUser);
- } catch (IOException e) {
- e.printStackTrace();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } finally {
- IOUtils.closeQuietly(ois);
- try {
- FileUtils.forceDelete(file);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- }
- }
-
- //OutPut:
- //User{name='hollis', age=23}
- //User{name='hollis', age=23}
- public class User1 implements Externalizable {
-
- private String name;
- private int age;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getAge() {
- return age;
- }
-
- public void setAge(int age) {
- this.age = age;
- }
-
- /*
- //需要重写此方法否则反序列化时对象属性皆为默认值
- public void writeExternal(ObjectOutput out) throws IOException {
- }
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- }
- */
-
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject(name);
- out.writeInt(age);
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- name = (String) in.readObject();
- age = in.readInt();
- }
-
- @Override
- public String toString() {
- return "User{" +
- "name='" + name + '\'' +
- ", age=" + age +
- '}';
- }
- }
- public class ExternalizableDemo1 {
- //为了便于理解和节省篇幅,忽略关闭流操作及删除文件操作。真正编码时千万不要忘记
- //IOException直接抛出
- public static void main(String[] args) throws IOException, ClassNotFoundException {
- //Write Obj to file
- ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("tempFile"));
- User1 user = new User1();
- user.setName("hollis");
- user.setAge(23);
- oos.writeObject(user);
- //Read Obj from file
- File file = new File("tempFile");
- ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
- User1 newInstance = (User1) ois.readObject();
- //output
- System.out.println(newInstance);
- }
- }
- //OutPut:
- //User{name='hollis', age=23}
Java中的类通过实现 java.io.Serializable 接口以启⽤其序列化功能。 未实现此接口的类将⽆法使其任何状态序列化或反序列化。
可序列化类的所有⼦类型本⾝都是可序列化的。
序列化接口没有⽅法或字段, 仅用于标识可序列化的语义。
当试图对⼀个对象进⾏序列化的时候, 如果遇到不⽀持Serializable 接口的对象。 在此情况下, 将抛NotSerializableException。
如果要序列化的类有⽗类, 要想同时将在⽗类中定义过的变量持久化下来, 那么⽗类也应该集成java.io.Serializable接口。
Externalizable继承了Serializable, 该接口中定义了两个抽象⽅法:writeExternal()与readExternal()。 当使⽤Externalizable接口来进⾏序列化与反序列化的时候需要开发⼈员重写writeExternal()与readExternal()⽅法。
如果没有在这两个⽅法中定义序列化实现细节, 那么序列化之后, 对象内容为空。
实现Externalizable接口的类必须要提供⼀个public的⽆参的构造器。
所以, 实现Externalizable, 并实现writeExternal()和readExternal()⽅法可以指定序列化哪些属性。
serialVersionUID是Long类型的变量,用于判断可序列化类反序列化时判断版本一致性。
serialVersionUID适用于Java的序列化机制。简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。
具体的序列化过程是这样的:序列化操作的时候系统会把当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致,如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。
serialVersionUID有两种显示的生成方式:
一是默认的1L,比如:private static final long serialVersionUID = 1L;
二是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。