Java中的序列化机制

本文深入探讨Java序列化机制,包括其意义、常见序列化技术如JSON和Protobuf,以及Serializable和Externalizable接口。强调了serialVersionUID的重要性,解释了静态变量不参与序列化的原因,介绍了如何使用Transient关键字避免敏感数据序列化。同时,文章提醒了序列化带来的潜在问题,如灵活性降低、安全漏洞等,并以Dubbo异常处理机制为例,阐述了序列化兼容性的重要性。
摘要由CSDN通过智能技术生成


先抛出序列化相关几个面试问题,各位看看能否答得上来?

  1. Java序列化机制的意义是什么?
  2. 你知道哪些序列化技术?
  3. 如何自定义序列化内容?
  4. serialVersionUID有什么用?
  5. 静态变量能否序列化?
  6. 某个字段(比如密码字段)不想序列化的话,怎么办?
  7. 序列化机制有什么缺点?
  8. Dubbo中的异常处理机制了解么?为什么要这么设计?

面试题是抛砖引玉,了解其背后原理才是目的,话不多说,发车了

序列化的意义

  1. 我们在内存中创建可复用的 Java 对象,但一般情况下,只有当 JVM 处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比 JVM 的生命周期更长。但在现实应用中,就可能要求在 JVM 停止运行之后能够保存(持久化)指定的对象,比如将用户数据保存在磁盘中、数据库中,并在将来重新读取被保存的对象。

  2. 不同Java系统之间经常会有交换数据、通信的需求,但是网络中的数据传输都是以字节流的形式,因此发送方系统有必要把对象数据转化成字节流数据来在网络中传输,而接收方系统接收到字节流后再反序列化成Java对象。Dubbo这种RPC通信框架中,Java对象就必须实现序列化接口。

总得来说:Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。从而达到网络传输、本地存储的效果

  1. Java序列化机制的意义是什么?已经有了答案

市面上的序列化技术

盗用网上一张图来说明

其中重点提一下JSON和Protobuf, JSON 和 protobuf 之间最显著的区别是 JSON 是基于文本的,并且是人类可读的,而 protobuf 是二进制的,但效率更高;JSON 是一种专门的数据表示,而 protobuf 提供模式(类型)来记录和执行适当的用法。虽然 protobuf 比 JSON 更有效,但是 JSON 对于基于文本的表示非常有效。虽然 protobuf 是一种二进制表示,但它确实提供了另一种文本表示,可用于需要具备人类可读性的场景
在这里插入图片描述

  1. 你知道哪些序列化技术?这里也有了答案

序列化接口Serializable、Externalizable

上面提到了很多序列化技术,当然本文重点是Java中的序列化

Serializable

Java中实现对象的可序列化非常简单,相关Java类实现 Serializable 接口即可,如图所示

	@Getter
    @Setter
    static class User implements Serializable {
   
    	//序列化id
	    private static final long serialVersionUID = 1L;
        private Long userId;
        private String userName;
    }

再来看看把User对象持久化到磁盘,并从磁盘读取后反序列化的例子,可以看到userId、userName被持久化下来,并能成功读取磁盘文件并反序列成Java对象
在这里插入图片描述

Externalizable

实现了Serializable接口的对象,Java已经为我们提供了内置的序列化功能,那么如果想自己自定义实现序列化内容呢,该怎么做?

Externalizable接口继承自Serializable接口,同时添加了writeExternalreadExternal方法用于实现自定义序列化功能。

修改上述User对象,并实现Externalizable接口

注意: 使用Externalizable接口的对象必须要有一个无参构造函数

	@Getter
    @Setter
    static class User implements Externalizable {
   
        private static final long serialVersionUID = 1L;
        private Long userId;
        private String userName;

        public User() {
   
        }

        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
   
            out.writeObject(userId);
            out
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值