Java面试题-Java核心基础-第十三天(序列化)

目录

一、Java序列化与反序列化是什么?

二、为什么需要序列化与反序列化?

三、序列化的实现方式有哪些?

四、什么是serialVersionUID?

五、为什么还要显示指定serialVersionUID

六、serialVersionUID什么时候修改?

七、Java序列化如果有些字段不想序列化,怎么办?

八、静态变量会序列化吗?


一、Java序列化与反序列化是什么?

Java序列化就是将对象转为字节序列

Java反序列化就是将字节序列转为内存中的对象

二、为什么需要序列化与反序列化?

其实大的来说就是为了保存对象的信息 状态信息 因为JVM一旦关闭 其对象也会被销毁 如何持久化对象就需要使用到序列化机制

另外就是为了便于网络传输传输信息,传输字节序列给对方,对方接收到再进行反序列化就能获取到对象信息,像RPC或者是OpenFeign远程调用就是将对象进行序列化与反序列化的过程(其实就是实现分布式对象,多个服务可以使用同一对象)

除此之外,序列化与反序列化机制还能用于实现深拷贝,序列化不仅只序列化当前对象,其对象里面的里面也会递归的序列化

三、序列化的实现方式有哪些?

类实现Serializable接口 或者是实现Externalizable接口

实现Serializable接口的方式很简单,只需要实现这个接口,不需要实现里面的任何方法,因为里面就没方法,然后在类里面指定一个serialVersionUID就行 注意这个必须是static final long的

而实现Externalizable 接口的方式,就更加的灵活了,可以指定我们需要序列化的字段,而如何指定呢?就通过实现Externalizable接口接口中的readExternal和writeExternal方法就可以了

例子:

java 复制代码
public class User implements Externalizable {

   private String name;
   private int age;

   public String getName() {
       return name;
   }
   public void setName(String name) {
       this.name = name;
   }
   public void writeExternal(ObjectOutput out) throws IOException {
       out.writeObject(name);
   }
   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
       name = (String) in.readObject();
   }

   @Override
   public String toString() {
       return "User{" +
               "name='" + name +
               '}';
   }
}

两者的对比:

Serializable接口更为简单,它是按照系统默认的序列化规则,能序列化所有属性。但是效率不高

Externalizable接口需要自己重写两个方法,可以指定序列化字段,如果不重写的话,默认是属性类型的默认值 效率高

四、什么是serialVersionUID?

就是一个类的标识,需要依靠这个来反序列化。它的过程是:拿到序列化中的serialVersionUID值,然后与本地的类的serialVersionUID作比较,如果相同则反序列化成本地类对象,如果不同则序列化失败

五、为什么还要显示指定serialVersionUID

如果不显示指定,那么这个值就会根据类的属性来自动生成有一个serialVersionUID值,因此如果类中属性变化了,这个值就会发生变化。

如果再我们序列化之后修改了类中的属性,那么此时这个serialVersionUID值就会与它原先当初序列化时类中的serialVersionUID不一样,所以就会反序列化失败。

因此一般我们要手动的指定一个serialVersionUID值

六、serialVersionUID什么时候修改?

一般的时候不要修改,除非软件不兼容的情况 因为不兼容 所以不允许类随意发生改变

七、Java序列化如果有些字段不想序列化,怎么办?

使用transient修饰 或者类实现Externalizable接口的方式重写方法指定

八、静态变量会序列化吗?

不会,因为静态变量属于类,而序列化的是对象的信息。

至于为什么静态的serialVersionUID可以被序列化 是因为JVM作了特殊判断,因为需要依靠它来进行反序列化

相关推荐
Javatutouhouduan2 天前
深入学习JVM底层原理:JVM源码剖析与实例详解
java·jvm·java虚拟机·java面试·后端开发·java程序员·java性能优化
Java爱好狂.3 天前
Redis高级笔记:原理+集群+应用+拓展+源码
java·数据库·redis·spring·java面试·后端开发·java八股文
Javatutouhouduan6 天前
阿里2026最新Java面试核心讲(终极版)
java·java面试·java并发·后端开发·java程序员·java八股文·java性能优化
devilnumber11 天前
java的NIO框架Netty、Mina、Grizzly 和 Jetty 四种对比
java·nio·java面试·jetty
__土块__13 天前
Java 大厂一面模拟:从线程池拒绝策略到分布式锁选型的连环压问
线程池·分布式锁·redisson·java面试·拒绝策略·大厂一面·kafka幂等
__土块__15 天前
Java 大厂一面模拟:从类加载器到热点Key治理的连续压问
jvm·spring aop·java面试·类加载·大厂一面·mysql间隙锁·redis缓存雪崩
__土块__15 天前
Java 大厂一面模拟:从线程本地存储到分库分表路由的连环拷问
kafka·线程池·分库分表·java面试·threadlocal·缓存一致性·大厂一面
却话巴山夜雨时i15 天前
互联网大厂Java面试:从Spring Boot到Kafka的业务场景深度剖析
spring boot·redis·spring cloud·微服务·kafka·prometheus·java面试
__土块__16 天前
Java 大厂一面模拟:从线程池调优到 Spring 事务传播的深度追问
线程池·java面试·spring事务·消息幂等·redis分布式锁·mysql死锁·大厂一面
却话巴山夜雨时i17 天前
互联网大厂Java面试场景:Spring Boot、微服务与Redis实战解析
spring boot·redis·微服务·kafka·prometheus·java面试·电商场景