1、简述
Serialization(序列化) 是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。
在分布式环境中,经常需要将Object从这一端网络或设备传递到另一端,这就需要有一种可以在两端传输数据的协议。Java序列化机制就是为了解决这个问题而产生的。
2、示例
参照如下案例:
序列化后的实体类:
public class User 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; } }
序列化:
public class SerialTest{ public static void main(String[] args) { try { PrintStream fos = new PrintStream(new FileOutputStream("D:/user.txt"),false, "UTF-8"); ObjectOutputStream oos = new ObjectOutputStream(fos); User ts = new User(); ts.setName("zhangsan"); oos.writeObject(ts); oos.flush(); oos.close(); } catch (IOException e) { e.printStackTrace(); } } }
反序列化:
public class DeSerialTest { public static void main(String[] args) { FileInputStream fis = null; try { fis = new FileInputStream("D:/user.txt"); ObjectInputStream oin = new ObjectInputStream(fis); User ts = (User) oin.readObject(); System.out.println("name = "+ts.getName()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } 执行结果为 : name = zhangsan
3. 注意事项:
(1)对继承父类的子类序列化
父类中的字段不参与序列化,只是将其初始化而已,因此父类中需要无参构造器
(2)transient 关键字
使用transient关键字来修饰变量,然后进行序列化(在实现serializable接口情况下)效果其实和父类的序列化一样,它所修饰的变量不参与序列化。这里就不举例说明了,自己可以写个案例测试下。
另外transient关键字只能修饰变量, 不能修饰类和方法。
(3)static关键字
使用static关键字来修饰变量,不管有没有transient修饰,同样不参与序列化(在实现serializable接口情况下)。
(4)Externalizable接口
Externalizable接口extends Serializable接口,而且在其基础上增加了两个方法:writeExternal()和readExternal()。这两个方法会在序列化和反序列化还原的过程中被自动调用,以便执行一些特殊的操作。
与Serizable对象不同,使用Externalizabled,就意味着没有任何东西可以自动序列化, 为了正常的运行,我们需要在writeExtenal()方法中将自对象的重要信息写入,从而手动的完成序列化。对于一个Externalizabled对象,对象的默认构造函数都会被调用(包括哪些在定义时已经初始化的字段),然后调用readExternal(),在此方法中必须手动的恢复数据。这就说明在Externalizable接口下不管是transient或static修饰的变量,如果没有指定写入,就会序列化。
参考博文:
https://www.cnblogs.com/yuanfy008/p/8269337.html