Java 序列化与反序列化
副标题[/!--empirenews.page--]
1、什么是序列化?为什么要序列化? Java 序列化就是指将对象转换为字节序列的过程,而反序列化则是只将字节序列转换成目标对象的过程。 我们都知道,在进行浏览器访问的时候,我们看到的文本、图片、音频、视频等都是通过二进制序列进行传输的,那么如果我们需要将Java对象进行传输的时候,是不是也应该先将对象进行序列化?答案是肯定的,我们需要先将Java对象进行序列化,然后通过网络,IO进行传输,当到达目的地之后,再进行反序列化获取到我们想要的对象,最后完成通信。
2、如何实现序列化 2.1、使用到JDK中关键类 ObjectOutputStream 和ObjectInputStream ObjectOutputStream 类中:通过使用writeObject(Object object) 方法,将对象以二进制格式进行写入。 ObjectInputStream 类中:通过使用readObject()方法,从输入流中读取二进制流,转换成对象。
2.2、目标对象需要先实现 Seriable接口
我们创建一个Student类: public class Student implements Serializable { private static final long serialVersionUID = 3404072173323892464L; private String name; private transient String id; private String age; @Override public String toString() { return "Student{" + "name='" + name + ''' + ", id='" + id + ''' + ", age='" + age + ''' + '}'; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public Student(String name, String id) { System.out.println("args Constructor"); this.name = name; this.id = id; } public Student() { System.out.println("none-arg Constructor"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } }
代码中Student类实现了Serializable 接口,并且生成了一个版本号: private static final long serialVersionUID = 3404072173323892464L; 首先: 1、Serializable 接口的作用只是用来标识我们这个类是需要进行序列化,并且Serializable 接口中并没有提供任何方法。 2、serialVersionUid 序列化版本号的作用是用来区分我们所编写的类的版本,用于判断反序列化时类的版本是否一直,如果不一致会出现版本不一致异常。 3、transient 关键字,主要用来忽略我们不希望进行序列化的变量
2.3、将对象进行序列或和反序列化 2.3.1 第一种写入方式: public static void main(String[] args){ File file = new File("D:/test.txt"); Student student = new Student("孙悟空","12"); try { ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file)); outputStream.writeObject(student); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } try { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file)); Student s = (Student) objectInputStream.readObject(); System.out.println(s.toString()); System.out.println(s.equals(student)); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } 创建对象Student ,然后通过ObjectOutputStream类中的writeObject()方法,将对象输出到文件中。 然后通过ObjectinputStream 类中的readObject()方法反序列化,获取对象。
2.3.2 第二种写入方式: 在Student 类中实现writeObject()和readObject()方法: private void writeObject(ObjectOutputStream objectOutputStream) throws IOException { objectOutputStream.defaultWriteObject(); objectOutputStream.writeUTF(id); } private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException { objectInputStream.defaultReadObject(); id = objectInputStream.readUTF(); } 通过这中方式进行序列话,我们可以自定义想要进行序列化的变量,将输入流和输出流传入对线实例中,然后进行序列化以及反序列化。
2.3.3 第三种写入方式: Student 实现 Externalnalizable接口 而不实现Serializable 接口 Externaliable 接口是 Serializable 的子类,有着和Serializable接口同样的功能: public class Student implements Externalizable { private static final long serialVersionUID = 3404072173323892464L; private String name; private transient String id; private String age; @Override public String toString() { return "Student{" + "name='" + name + ''' + ", id='" + id + ''' + ", age='" + age + ''' + '}'; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public Student(String name, String id) { System.out.println("args Constructor"); this.name = name; this.id = id; } public Student() { System.out.println("none-arg Constructor"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(name); out.writeObject(id); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { name = (String) in.readObject(); id = (String) in .readObject(); } }
(编辑:PHP编程网 - 黄冈站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |