java序列化常见面试题

1.什么是序列化

       序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。   序列化是为了解决在对对象流进行读写操作时所引发的问题。序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的, 然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

2.序列化和反序列化

  1. •序列化:java.io.ObjectOutputStream 类的 writeObject() 方法可以实现序列化
  2. •反序列化:java.io.ObjectInputStream 类的 readObject() 方法用于实现反序列化。
  3.   

 3.在 Java 中的序列化和反序列化过程中使用哪些方法?

        这是很常见的面试问题, 在序列化基本上面试官试图知道: 你是否熟悉 readObject() 的用法、writeObject()、readExternal() 和 writeExternal()。Java 序列化由java.io.ObjectOutputStream类完成。该类是一个筛选器流, 它封装在较低级别的字节流中, 以处理序列化机制。要通过序列化机制存储任何对象, 我们调用 ObjectOutputStream.writeObject(savethisobject), 并反序列化该对象, 我们称之为 ObjectInputStream.readObject()方法。调用以 writeObject() 方法在 java 中触发序列化过程。关于 readObject() 方法, 需要注意的一点很重要一点是, 它用于从持久性读取字节, 并从这些字节创建对象, 并返回一个对象, 该对象需要类型强制转换为正确的类型。

4、序列化并不保存静态变量

        序列化子父类说明 要想将父类对象也序列化,就需要让父类也实现 Serializable 接口。

5、writeObject readObject 自定义序列化策略

        在类中增加 writeObject readObject 方法可以实现自定义序列化策略。

6、保存(持久化)对象及其状态到内存或者磁盘

        Java 平台允许我们在内存中创建可复用的 Java 对象,但一般情况下,只有当 JVM 处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比 JVM 的生命周期更长。 但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java  对象序列化就能够帮助我们实现该功能。

7.序列化的用途?

  1. •序列化可以将对象的字节序列持久化-保存在内存、文件、数据库中。
  2. •在网络上传送对象的字节序列。
  3. •RMI(远程方法调用)

8、序列化对象以字节数组保持-静态成员不保存

        使用 Java 对象序列化, 在保存对象时,会把其状态保存为一组字节,在未来, 再将这些字节组装成对象。必须注意地是,  对象序列化保存的是对象的状态,即它的成员变量。由此可知,对象序列化不会关注类中的静态变量。

9、序列化用户远程对象传输

        除了在持久化对象时会用到对象序列化之外,当使用  RMI(远程方法调用),或在网络中传递对象时,都会用到对象序列化。 Java序列化API为处理对象序列化提供了一个标准机制,该API简单易用。

10、序列化(深 clone 一中实现)

        在 Java 语言里深复制一个对象,常常可以先使对象实现 Serializable 接口,然后把对象(实际上只是对象的一个拷贝)写到一个流里,再从流里读出来,便可以重建对象。

11、Transient 关键字阻止该变量被序列化到文件中

  1. 在变量声明前加上 Transient 关键字,可以阻止该变量被序列化到文件中,在被反序列 化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null
  2. 服务器端给客户端发送序列化对象数据,对象中有一些数据是敏感的,比如密码字符串  等,希望对该密码字段在序列化时,进行加密,而客户端如果拥有解密的密钥,只有在  客户端进行反序列化时,才可以对密码进行读取,这样可以一定程度保证序列化对象的 数据安全。

12.serialVersionUID

        serialVersionUID 有什么作用,如何使用 serialVersionUID?

        serialVersionUID 是 Java 为每个序列化类产生的版本标识。它可以用来保证在反序列时,发送方发送的和接受方接收的是可兼容的对象。如果接收方接收的类的 serialVersionUID 与发送方发送的 serialVersionUID 不一致,会抛出 InvalidClassException。

        如果可序列化类没有显式声明 serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认 serialVersionUID 值。尽管这样,还是建议在每一个序列化的类中显式指定 serialVersionUID 的值。因为不同的 jdk 编译很可能会生成不同的 serialVersionUID 默认值,从而导致在反序列化时抛出 InvalidClassExceptions 异常。

        serialVersionUID 字段必须是 static final long 类型。

 13.如果类是可序列化的, 但其超类不是, 则反序列化后从超级类继承的实例变量的状态如何?

        Java 序列化过程仅在对象层次都是可序列化结构中继续, 即实现 Java 中的可序列化接口, 并且从超级类继承的实例变量的值将通过调用构造函数初始化, 在反序列化过程中不可序列化的超级类。一旦构造函数链接将启动, 就不可能停止, 因此, 即使层次结构中较高的类实现可序列化接口, 也将执行构造函数。正如你从陈述中看到的, 这个序列化面试问题看起来非常棘手和有难度, 但如果你熟悉关键概念, 则并不难。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值