java序列化和反序列化,面试必备
最近阅读Serializable接口和Externalizable接口的源码,并结合了一些资料,对面试过程中与序列化相关的内容做了一些总结。 一、序列化、反序列化、使用场景、意义。 序列化:将对象写入IO流中; 反序列化:从IO流中恢复对象; 意义:序列化机制允许将实现序列化的Java对象转换为字节序列,并将字节序列保存在磁盘中,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使地对象可以脱离程序的运行而独立存在。 使用场景:所有在网络上传输的对象都必须是可序列化的。如:RMI (远程方法调用),传入的参数或返回的对象都是可序列化的,否则会出错。所有必须保存到磁盘的java对象都必须是可 Java序列化和反序列化是Java开发中常见且重要的概念,尤其在面试中常常被问及。序列化是指将一个Java对象转化为字节序列的过程,这样可以将对象的状态持久化到磁盘上或者在网络中进行传输。反序列化则是相反的过程,即从字节序列恢复成原来的对象。 一、序列化、反序列化、使用场景和意义 1. 序列化:通过实现`Serializable`接口,Java对象可以被转化为字节流,这使得对象的状态能够被保存或在网络间传递。例如,当需要在网络上的不同系统之间交换数据时,或者在分布式环境中(如RMI - 远程方法调用)使用对象,序列化就显得至关重要。 2. 反序列化:从字节流中重建对象,恢复其原始状态。这个过程是序列化的逆操作,通常用于加载保存的数据或接收网络传输的对象。 3. 使用场景:网络通信(如RMI、HTTP服务)、持久化存储(如数据库、文件系统)、分布式计算、缓存等。 4. 意义:序列化允许对象脱离程序运行环境独立存在,便于数据交换和持久化存储。 二、实现序列化的方式 1. 实现`Serializable`接口:这是最常用的方式,只需在类声明中添加`implements Serializable`,无需编写额外代码,Java会自动处理对象的序列化。但是这种方式可能会导致安全问题(如反序列化攻击),并且性能相对较低。 2. 实现`Externalizable`接口:这种方式更加灵活,开发者需要手动控制哪些字段参与序列化和反序列化,通过自定义`writeExternal`和`readExternal`方法。这种方式可以提高性能,减少序列化开销,但需要更多的编码工作。 三、使用`Serializable`接口实现序列化 1. 示例代码: ```java public class Person implements Serializable { private String name; private String age; // 构造函数和toString方法省略... public static void main(String[] args) { try { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Person.txt")); Person p = new Person("baby", "12"); oos.writeObject(p); oos.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 上述代码展示了如何将`Person`对象序列化到名为"Person.txt"的文件中。 2. 反序列化: ```java public class ReadObject { public static void main(String[] args) { try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Person.txt")); Person p = (Person) ois.readObject(); ois.close(); System.out.println(p); } catch (Exception e) { e.printStackTrace(); } } } ``` 以上代码演示了如何从"Person.txt"文件中读取并反序列化`Person`对象。 四、注意事项 1. 安全问题:不安全的反序列化可能导致代码执行风险,因此在反序列化时需谨慎处理,避免反序列化不受信任的数据。 2. `transient`关键字:用于标记不希望序列化的成员变量。 3. `serialVersionUID`:默认由JVM生成,用于版本控制,当类发生改变时,可能需要手动更新此ID以避免反序列化异常。 4. 继承关系:如果父类没有实现`Serializable`,子类实现该接口,父类的所有非静态、非瞬态字段也会被序列化。 Java序列化和反序列化是处理对象持久化和网络通信的关键技术。了解其原理和实现方式,对于Java开发者来说是必不可少的技能,也是面试中的常考点。