Java序列化中的Serializable是怎样的存在!


JDK中对Serializable接口的定义下:

Serializability of a class is enabled by the class implementing the java.io.Serializable interface. Classes that do not implement this interface will not have any of their state serialized or deserialized. All subtypes of a serializable class are themselves serializable. The serialization interface has no methods or fields and serves only to identify the semantics of being serializable.

白话文表述就是: 类的可序列化性早实现Serializable接口来启用,未实现此接口的类不能进行序列化和反序列化。同时呢,一个类变成可序列化后,它的所有子类也将可序列化。Serializable接口没有方法,没有属性定义,仅仅是个可序列化标识接口。

看起来是不是很简单,但是JAVA本身的这个序列化却是牵扯很广大呀,里面门道不见得比那些高大上的序列化家族少哇。

一. 一个类能不能被序列化,到底有哪些要求?先从最基础的来说,

1)首先,上面已经说了,必须得实现 Serializable 接口,这是第一步,可以理解为这是一个开关。接下来就到这个类自身的定义了,我们平常呢,定义一个类,里面肯定有一些属性,这些属性呢有各自的类型。那如果我们需要这个类能正常被序列化的话呢,这个时候类里面的属性就不能随意定义了,比如:下面这个示例中

static class Vo1 implements Serializable { private int num; private String name; private Integer use; private FieldX fieldX; public Vo1(int num, String name, Integer use, FieldX fieldX) { this.num = num; this.name = name; this.use = use; this.fieldX = fieldX; } public Vo1(int num, String name, Integer use) { this.num = num; this.name = name; this.use = use; } @Override public String toString() { return new StringJoiner(", ", Vo1.class.getSimpleName() + "[", "]").add("num=" + num).add("name='" + name + "'").add("use=" + use).add("fieldX=" + fieldX).toString(); } }static class FieldX{ private String name; private String value; public FieldX(String name, String value) { this.name = name; this.value = value; } @Override public String toString() { return new StringJoiner(", ", FieldX.class.getSimpleName() + "[", "]").add("name='" + name + "'").add("value='" + value + "'").toString(); } } @Test void testSer() throws Exception{ Vo1 vo1 = new Vo1(123,"Test",100); Vo1 vo2 = new Vo1(123,"Test",100,new FieldX("F1","V1")); System.out.println("vo1"); try(ObjectOutputStream serializable=new ObjectOutputStream(new FileOutputStream("G://vo1.txt"))) { serializable.writeObject(vo1); } System.out.println("vo2"); try(ObjectOutputStream serializable=new ObjectOutputStream(new FileOutputStream("G://vo2.txt"))) { serializable.writeObject(vo2); } }


,vo1实例可以正常序列化,而vo2实例无法正常序列化,提示的是FieldX类型不可序列化。

2)所以要保证一个类可以被正常序列化,在实现Serializable接口的基础上,还得保证此类中所有需要被序列化的属性都满足可序列化条件,FieldX类也同样需要去实现接口Serializable,以此类推。那如果存在不需要被序列化的属性怎么办呢?我们后面再补充此内容。

3) 类中所有属性不包含类属性哦,就是类里面的静态变量等是不在上述范围内的,因为序列化本质。二. 类序列化目的是什么?简单来说就是:我们的程序在运行过程中本身产生的对象实例,本身是在JVM中存储的,说直白点就是只存在于内存中,这也就意味着在程序终止时这些内存中的对象实例理论上都会被释放回收。那么,如果说我们有一些场景需要在程序运行后产生的对象实例在下次程序运行时仍然可以访问和使用,甚至于一个程序中产生的对象实例要在另外的程序中可以访问并使用,要怎么满足这些应用场景呢?答案是序列化。

序列化有两个主要目的:

1 是对象实例状态的持久化,存储到硬盘或其它可以持久存储的介质,以保证在程序终止时不会随内存释放而消失的,可以持久保存。

2 是对象实例的共享,序列化后的对象实例可以通过网络等介质发送和传播,可以在其它程序中访问和使用。

三. JDK序列化的优劣.

目前来说,在JAVA领域有很多优秀的序列化支持,JDK本身的序列化也被诸多诟病,其性能并不具备优势。其主要的优势在本人看来可能就是通用性和简单化了,所以在一些性能不敏感的节点(要求不高),JDK序列化仍然保持活跃。如果在一些性能敏感的节点,可能大家需要去参考一些更具优势的协议,如:protobuf,json等序列化方式。

本期旨在简单介绍JDK序列化的基本内容,下期继续来讲"JDK序列化中的坑!"。


展开阅读全文

页面更新:2024-05-14

标签:目的   持久   实例   属性   接口   定义   对象   内存   性能   程序

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top