香河住房和建设局网站,诸城网站建设多少钱,绍兴百度seo排名,九脉堂是做网站的文章目录 1. 简介2. Java中的序列化3. Java中的反序列化4. Java序列化中的常见问题和解决策略5. 自定义序列化6. 常见问题及解答7. 使用场景8. 结尾 1. 简介
序列化和反序列化的本质是解决在进行远程通信和持久化数据时#xff0c;如何保存和恢复数据的问题。
** 序列化如何保存和恢复数据的问题。
** 序列化** 将数据结构或对象转换成二进制字节流的过程** 反序列化 ** 将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程
为什么要进行序列化和反序列化操作? 其实主要是为了持久化和进行传输我们都知道在Java 中一些数据都是以对象的形式存在的那如果我想把对象传输其他人怎么办
那肯定是不能直接传输的假如我们要进行网络传输传输的过程中是不能传输Java 对象的因为底层的实现并不知道Java 对象的存在我们一般都是传输字节所以我们需要能够进行传输的形式序列化就是这个操作我们将Java 对象序列化为一个字节数组这样就可以进行传输了。
这个原理不仅在Java中在所有需要进行远程通信和数据存储的编程语言中都存在。
2. Java中的序列化
为了在Java中实现序列化我们需要完成以下两个步骤。
首先让我们要序列化的类实现Serializable接口。下面是一个实现了Serializable接口的Person类。
public class Person implements Serializable {private String name;// getter 和 setter 方法省略
}然后我们可以使用java.io.ObjectOutputStream类将Person对象写入到硬盘中如下所示
Person person new Person();
person.setName(Grace);try (FileOutputStream fos new FileOutputStream(person.obj);ObjectOutputStream oos new ObjectOutputStream(fos)) {oos.writeObject(person);
} catch (IOException e) {e.printStackTrace();
}3. Java中的反序列化
反序列化就是将序列化的字节流恢复成原来的对象。我们可以通过java.io.ObjectInputStream类来完成这个过程如下所示
try (FileInputStream fis new FileInputStream(person.obj);ObjectInputStream ois new ObjectInputStream(fis)) {Person person (Person) ois.readObject();System.out.println(person.getName());
} catch (IOException | ClassNotFoundException e) {e.printStackTrace();
}4. Java序列化中的常见问题和解决策略
序列化并不总是那么简单。我们可能会遇到版本控制问题、子类序列化以及某些字段不应该被序列化的问题。 版本控制问题 在序列化对象中serialVersionUID是JAVA为了有效地实现序列化所引入的。serialVersionUID作为版本控制在反序列化过程中JAVA虚拟机会根据版本号确保序列化类的一致性。如果对象的版本号不一致反序列化过程就会失败抛出InvalidClassException异常。示例 public class Person implements Serializable {private static final long serialVersionUID 1L;// 其他代码省略
}子类序列化 在Java中父类通过实现Serializable接口子类可以由此自动实现序列化反之则不行。当子类需要序列化而父类并未实现序列化接口时可以通过在子类添加一个父类的构造器来解决。这样的示例 public class Person {private String name;Person(String name){this.name name;// 其他代码省略}
}public class Employee extends Person implements Serializable {private int employeeId;Employee(String name, int employeeId) {super(name);this.employeeId employeeId;// 其他代码省略}
}transient关键字 在序列化过程中可能某些字段并不需要序列化比如说一些敏感信息如密码、银行卡号等。这时可以使用transient关键字标记不需要序列化的字段。值得注意的是被transient关键字标记的字段在反序列化回来后将为null。示例 public class Person implements Serializable {private String name;private transient String password; // 此字段不会被序列化// getter 和 setter 方法省略
}5. 自定义序列化
有时候我们可能想要更多地控制序列化的过程。Java为我们提供了自定义序列化的方法——通过在我们的类中重写writeObject(ObjectOutputStream out)和readObject(ObjectInputStream in)方法我们就可以控制对象的序列化过程。示例
public class Person implements Serializable {private String name;private transient String password; // 此字段不会被序列化private void writeObject(ObjectOutputStream out) throws IOException {out.defaultWriteObject();out.writeObject(password); }private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {in.defaultReadObject();password (String) in.readObject(); }// getter 和 setter 方法省略
}6. 常见问题及解答
没有实现Serializable接口的类的对象能否序列化 不可以。如果对象的类没有实现 Serializable 接口那么将无法通过ObjectOutputStream进行序列化。静态变量参与序列化吗 不参与。因为static的变量属于类级别的序列化只处理对象的状态即类的非静态字段。静态变量的生命周期和对象不同由JVM负责维护。如何控制是否序列化字段 对于不需要序列化的字段我们可以使用transient关键字。被transient修饰的字段在序列化时将被忽略反序列化时按照字段类型的默认值填充。如何保证序列化对象的安全性 对于需要序列化的敏感信息对象我们可以在序列化时加密反序列化时解密来保证安全性。另外选择可靠的存储和传输方式也是重要的安全保障。
7. 使用场景
序列化被广泛应用于各种场景如远程调用RMI或EJB持久化HibernateHTTP会话在集群节点间的复制等。理解序列化及反序列化的原理和实现对掌握Java及各种Java框架和中间件至关重要。
下面是序列化和反序列化常见应用场景
对象在进行网络传输比如远程方法调用 RPC 的时候之前需要先被序列化接收到序列化的对象之后需要再进行反序列化将对象存储到文件之前需要进行序列化将对象从文件中读取出来需要进行反序列化将对象存储到数据库如 Redis之前需要用到序列化将对象从缓存数据库中读取出来需要反序列化将对象存储到内存之前需要进行序列化从内存中读取出来之后需要进行反序列化。
8. 结尾
序列化和反序列化看似简单的概念但实则包含了许多复杂的细节。希望通过这篇文章能够帮助大家更深入地理解序列化和反序列化的过程以及如何在实际编程中使用序列化。
如文章有任何疑问欢迎提出 欢迎大家访问我的个人博客 无限进步的博客