概念

 

  • 实现 Serializable 接口, 它只是一个标记接口,不实现也能够进行序列化
  • RMI: 远程方法调用
  • RPC: 远程过程调用

序列化ID

复制代码
解决了序列化与反序列出现代码不一致的问题, 不一致将导致序列化失败 private static final long serialVersionUID = 1L; // 便于进行代码版本控制private static final long serialVersionUID = -5453781658505116230L; //便于控制代码结构
复制代码

 

静态变量序列化

  • x*- 序列化的是对象,而不是类,静态变量属于类级别,所以序列化不会保存静态变量

 

父类序列化与Trancient关键字

  • 一个子类实现了 Serializable 接口,它的父类没有实现 Serializable 接口,那么序列化子类时,父类的值都不会进行保存
    •   需要父类保存值 ,就需要让父类也实现Serializable 接口
    •   取父对象的变量值时,它的值是调用父类无参构造函数后的值,出现如 int 型的默认是 0,string 型的默认是 null, 要指定值,那么需要在父类构造方法中进行指定
  • Trancient关键字指定的内容将不会被保存(阻止序列化)
    •   在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 nul
    • 使用继承关系同样可以实现,Trancient一样的效果,,即为父类不需要实现Serializable接口

利用PutField getPutField字段进行加密

原理:

  • 1: 进行序列化时,JVM试图调用对象的writeObject() readObject() 方法(允许自己私有化实现)
  • 2:默认调用是 ObjectOutputStream 的 defaultWriteObject 方法以及 ObjectInputStream 的 defaultReadObject 方法
复制代码
private void writeObject(ObjectOutputStream out) {         try {             PutField putFields = out.putFields(); //放到            System.out.println("原密码:" + password);             password = "encryption";// 模拟加密            putFields.put("password", password);             System.out.println("加密后的密码" + password);             out.writeFields();         } catch (IOException e) {             e.printStackTrace();         }     }     private void readObject(ObjectInputStream in) {         try {             GetField readFields = in.readFields();             Object object = readFields.get("password", "");             System.out.println("要解密的字符串:" + object.toString());             password = "pass";// 模拟解密,需要获得本地的密钥        } catch (IOException e) {             e.printStackTrace();         } catch (ClassNotFoundException e) {             e.printStackTrace();         }     }  // 调用的时候直接调用 out的writeObject(),或者in的readObject() 即可
复制代码

 

序列化存储规则

 

  • 对同一对象两次写入文件, 第一次写入实际对象的序列化后的数据,第二次写入同一个对象的引用数据.(即为指向同一个对象)
    • 1: 节约了磁盘存储空间  
    • 2: 反序列化后的数据的值,应该是第一次保存的数据的值,(对于同一个对象第二次序列化,值是不会进行保存的)