当前位置:   article > 正文

Java基础之序列化_如何实现java序列化

如何实现java序列化

一、什么是序列化?

        序列化的定义是:将一个对象编码成一个字节流(I/O);而与之相反的操作被称为反序列化。

        序列化的目的是为了方便数据的传递以及存储到磁盘上(把一个Java对象写入到硬盘或者传输到网路上面的其它计算机,这时我们就需要将对象转换成字节流才能进行网络传输。对于这种通用的操作,就出现了序列化来统一这些格式)。

        简单来说序列化就是一种用来处理对象流的机制。将对象转化成字节序列后可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在。

二、如何实现序列化?
        1)实现Serializable接口
  1. public class User1 implements Serializable {
  2. private String name;
  3. private int age;
  4. public String getName() {
  5. return name;
  6. }
  7. public void setName(String name) {
  8. this.name = name;
  9. }
  10. public int getAge() {
  11. return age;
  12. }
  13. public void setAge(int age) {
  14. this.age = age;
  15. }
  16. @Override
  17. public String toString() {
  18. return "User{" +
  19. "name='" + name + '\'' +
  20. ", age=" + age +
  21. '}';
  22. }
  23. }
  1. public class SerializableDemo1 {
  2. public static void main(String[] args) {
  3. //Initializes The Object
  4. User1 user = new User1();
  5. user.setName("hollis");
  6. user.setAge(23);
  7. System.out.println(user);
  8. //Write Obj to File
  9. ObjectOutputStream oos = null;
  10. try {
  11. oos = new ObjectOutputStream(new FileOutputStream("tempFile"));
  12. oos.writeObject(user);
  13. } catch (IOException e) {
  14. e.printStackTrace();
  15. } finally {
  16. IOUtils.closeQuietly(oos);
  17. }
  18. //Read Obj from File
  19. File file = new File("tempFile");
  20. ObjectInputStream ois = null;
  21. try {
  22. ois = new ObjectInputStream(new FileInputStream(file));
  23. User1 newUser = (User1) ois.readObject();
  24. System.out.println(newUser);
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. } catch (ClassNotFoundException e) {
  28. e.printStackTrace();
  29. } finally {
  30. IOUtils.closeQuietly(ois);
  31. try {
  32. FileUtils.forceDelete(file);
  33. } catch (IOException e) {
  34. e.printStackTrace();
  35. }
  36. }
  37. }
  38. }
  39. //OutPut:
  40. //User{name='hollis', age=23}
  41. //User{name='hollis', age=23}
        2)实现Externalizable接口
  1. public class User1 implements Externalizable {
  2. private String name;
  3. private int age;
  4. public String getName() {
  5. return name;
  6. }
  7. public void setName(String name) {
  8. this.name = name;
  9. }
  10. public int getAge() {
  11. return age;
  12. }
  13. public void setAge(int age) {
  14. this.age = age;
  15. }
  16. /*
  17. //需要重写此方法否则反序列化时对象属性皆为默认值
  18. public void writeExternal(ObjectOutput out) throws IOException {
  19. }
  20. public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
  21. }
  22. */
  23. public void writeExternal(ObjectOutput out) throws IOException {
  24. out.writeObject(name);
  25. out.writeInt(age);
  26. }
  27. public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
  28. name = (String) in.readObject();
  29. age = in.readInt();
  30. }
  31. @Override
  32. public String toString() {
  33. return "User{" +
  34. "name='" + name + '\'' +
  35. ", age=" + age +
  36. '}';
  37. }
  38. }
  1. public class ExternalizableDemo1 {
  2. //为了便于理解和节省篇幅,忽略关闭流操作及删除文件操作。真正编码时千万不要忘记
  3. //IOException直接抛出
  4. public static void main(String[] args) throws IOException, ClassNotFoundException {
  5. //Write Obj to file
  6. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("tempFile"));
  7. User1 user = new User1();
  8. user.setName("hollis");
  9. user.setAge(23);
  10. oos.writeObject(user);
  11. //Read Obj from file
  12. File file = new File("tempFile");
  13. ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
  14. User1 newInstance = (User1) ois.readObject();
  15. //output
  16. System.out.println(newInstance);
  17. }
  18. }
  19. //OutPut:
  20. //User{name='hollis', age=23}
        3)ExternalizableSerializable的区别?

                Java中的类通过实现 java.io.Serializable 接口以启⽤其序列化功能。 未实现此接口的类将⽆法使其任何状态序列化或反序列化

                可序列化类的所有⼦类型本⾝都是可序列化的。

                序列化接口没有⽅法或字段,于标识可序列化的语义

                当试图对⼀个对象进⾏序列化的时候, 如果遇到不⽀持Serializable 接口的对象。 在此情况下, 将抛NotSerializableException

                如果要序列化的类有⽗类, 要想同时将在⽗类中定义过的变量持久化下来, 那么⽗类也应该集成java.io.Serializable接口。

                Externalizable继承了Serializable, 该接口中定义了两个抽象⽅法:writeExternal()与readExternal()。 当使⽤Externalizable接口来进⾏序列化与反序列化的时候需要开发⼈员重写writeExternal()与readExternal()⽅法。

                如果没有在这两个⽅法中定义序列化实现细节, 那么序列化之后, 对象内容为空。

                实现Externalizable接口的类必须要提供⼀个public⽆参的构造器。

                所以, 实现Externalizable, 并实现writeExternal()和readExternal()⽅法可以指定序列化哪些属性

三、serialVersionUID是什么,有什么作用,如何生成?

        serialVersionUID是Long类型的变量,用于判断可序列化类反序列化时判断版本一致性

        serialVersionUID适用于Java的序列化机制。简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。

        具体的序列化过程是这样的:序列化操作的时候系统会把当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致,如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。

        serialVersionUID有两种显示的生成方式:        
        一是默认的1L,比如:private static final long serialVersionUID = 1L;        
        二是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/767525
推荐阅读
相关标签
  

闽ICP备14008679号