java序列化实现
1. 什么是序列化,在java中如何实现序列化
一、什么是序列化:x0dx0a序列化理解成“打碎”是可以的,不过在书本上的名词就是将对象转换成二进制。x0dx0ax0dx0a二、在java中如何实现序列化:x0dx0a首先我们要把准备要序列化类,实现 Serializabel接口x0dx0a例如:我们要Person类里的name和age都序列化x0dx0aimport java.io.Serializable;x0dx0ax0dx0apublic class Person implements Serializable { //本类可以序列化x0dx0a private String name ;x0dx0a private int age ;x0dx0a x0dx0a public Person(String name,int age){x0dx0a this.name = name ;x0dx0a this.age = age ;x0dx0a }x0dx0a public String toString(){x0dx0a return "姓名:" + this.name + ",年龄" + this.age ;x0dx0a }x0dx0a}x0dx0ax0dx0a然后:我们将name和age序列化(也就是把这2个对象转为二进制,统族理解为“打碎”)x0dx0apackage org.lxh.SerDemo;x0dx0ax0dx0aimport java.io.File;x0dx0aimport java.io.FileOutputStream;x0dx0aimport java.io.ObjectOutputStream ;x0dx0ax0dx0apublic class ObjectOutputStreamDemo { //序列化x0dx0ax0dx0a public static void main(String[] args) throws Exception {x0dx0a//序列化后生成指定文件路径x0dx0a File file = new File("D:" + File.separator + "person.ser") ; ObjectOutputStream oos = null ;x0dx0a//装饰流(流)x0dx0a oos = new ObjectOutputStream(new FileOutputStream(file)) ; x0dx0a//实例化类x0dx0a Person per = new Person("张三",30) ; oos.writeObject(per) ;//把类对象序列化x0dx0a oos.close() ;x0dx0a }x0dx0a}
2. JAVA 压缩和序列化
压缩和序列化主要用在数据的存储和传输上,二者都是由IO流相关知识实现,这里统一介绍下。
全部章节传送门:
Java I/O类支持读写压缩格式的数据流,你可以用他们对其他的I/O流进行封装,以提供压缩功能。
GZIP接口比较简单,适合对单个数据流进行压缩,在Linux系统中使用较多。
ZIP格式可以压缩多个文件,而且可以和压缩工具进行协作,是经常使用的压缩方法。
JAR(Java Archive,Java 归档文件)是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件。为 J2EE 应用程序创建的 JAR 文件是 EAR 文件(企业 JAR 文件)。
JAR 文件格式以流行的 ZIP 文件格式为基础。与 ZIP 文件不同的是,JAR 文件不仅用于压缩和发布,而且还用于部署和封装库、组件和插件程序,并可被像编译器和 JVM 这样的工具直接使用。在 JAR 中包含特殊的文件,如 manifests 和部署描述符,用来指示工具如何处理特定的 JAR。
如果一个Web应用程序的目录和文件非常多,那么将这个Web应用程序部署到另一台机器上,就不是很方便了,我们可以将Web应用程序打包成Web 归档(WAR)文件,这个过程和把Java类文件打包成JAR文件的过程类似。利用WAR文件,可以把Servlet类文件和相关的资源集中在一起进行发布。在这个过程中,Web应用程序就不是按照目录层次结构来进行部署了,而是把WAR文件作为部署单元来使用。
一个WAR文件就是一个Web应用程序,建立WAR文件,就是把整个Web应用程序(不包括Web应用程序层次结构的根目录)压缩起来,指定一个.war扩展名。下面我们将第2章的Web应用程序打包成WAR文件,然后发布
要注意的是,虽然WAR文件和JAR文件的文件格式是一样的,并且都是使用jar命令来创建,但就其应用来说,WAR文件和JAR文件是有根本区别的。JAR文件的目的是把类和相关的资源封装到压缩的归档文件中,而对于WAR文件来说,一个WAR文件代表了一个Web应用程序,它可以包含 Servlet、HTML页面、Java类、图像文件,以及组成Web应用程序的其他资源,而不仅仅是类的归档文件。
在命令行输入jar即可查看jar命令的使用方法。
把对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为对象的过程称为对象的反序列化。
对象的序列化主要有两种用途:
java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
只有实现了Serializable的对象才能被序列化。对象序列化包括如下步骤:
对象反序列化的步骤如下:
创建一个可以可以序列化的对象。
然后进行序列化和反序列化测试。
serialVersionUID: 字面意思上是序列化的版本号,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量。
JAVA序列化的机制是通过判断类的serialVersionUID来验证的版本一致的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID于本地相应实体类的serialVersionUID进行比较。如果相同说明是一致的,可以进行反序列化,否则会出现反序列化版本一致的异常,即是InvalidCastException。
为了提高serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。
控制序列化字段还可以使用Externalizable接口替代Serializable借口。此时需要定义一个默认构造器,否则将为得到一个异常(java.io.InvalidClassException: Person; Person; no valid constructor);还需要定义两个方法(writeExternal()和readExternal())来控制要序列化的字段。
如下为将Person类修改为使用Externalizable接口。
transient修饰符仅适用于变量,不适用于方法和类。在序列化时,如果我们不想序列化特定变量以满足安全约束,那么我们应该将该变量声明为transient。执行序列化时,JVM会忽略transient变量的原始值并将默认值(引用类型就是null,数字就是0)保存到文件中。因此,transient意味着不要序列化。
静态变量不是对象状态的一部分,因此它不参与序列化。所以将静态变量声明为transient变量是没有用处的。
3. 什么是java序列化,如何实现java序列化
序 列 化: 指把堆内存中的Java对象数据,通过某种方式把对象存储到磁盘文件中或者传递给其他网络的节点(在网络上传输).我们把这个过程称之为序列化.
反序列化:把磁盘文件中的对象数据或者把网络节点上的对象数据,恢复成Java对象的过程.
为什么要做序列化:
1):在分布式系统中,需要共享的数据的JavaBean对象,都得做序列化,此时需要把对象再网络上传输,此时就得把对象数据转换为二进制形式.以后存储在HttpSession中的对象,都应该实现序列化接口(只有实现序列化接口的类,才能做序列化操作).
2):服务钝化:如果服务发现某些对象好久都没有活动了,此时服务器就会把这些内存中的对象,持久化在本地磁盘文件中(Java对象-->二进制文件).如果某些对象需要活动的时候,现在内存中去寻找,找到就使用,找不到再去磁盘文件中,反序列化我们得对象数据,恢复成Java对象.
需要做序列化的对象的类,必须实现序列化接口:java.io.Serializable接口(标志接口[没有抽象方法]).
底层会判断,如果当前对象是Serializable的实例,才允许做序列化. boolean ret = Java对象 instanceof Serializable;
在Java中大多数类都已经实现Serializable接口.
4. 什么是java序列化,如何实现序列化
简单来说,如果你只是自己同一台机器的同一个环境下使用同一个JVM来操作,序列化和反序列化是没必要的,当需要进行数据传输的时候就显得十分必要。比如你的数据写到文件里要被其他人的电脑的程序使用,或者你电脑上的数据需要通过网络传输给其他人的程序使用,像服务器客户端的这种模型就是一种应用,这个时候,大家想想,每个人的电脑配置可能不同,运行环境可能也不同,字节序可能也不同,总之很多地方都不能保证一致,所以为了统一起见,我们传输的数据或者经过文件保存的数据需要经过序列化和编码等操作,相当于交互双方有一个公共的标准,按照这种标准来做,不管各自的环境是否有差异,各自都可以根据这种标准来翻译出自己能理解的正确的数据。
除了在持久化对象时会用到对象序列化之外,当使用RMI(远程方法调用),或在网络中传递对象时,都会用到对象序列化。实现序列化:
1 首先要把准备要序列化类,实现 Serializabel接口
importjava.io.Serializable;
{
//本类可以序列化
privateStringname;
privateintage;
publicPerson(Stringname,intage)
{
this.name=name;this.age=age;
}
publicStringtoString()
{
return"姓名:"+this.name+",年龄"+this.age;
}
}
2 序列化
packageorg.lxh.SerDemo;
importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.ObjectOutputStream;
{
//序列化
publicstaticvoidmain(String[]args)throwsException
{
//序列化后生成指定文件路径
Filefile=newFile("D:"+File.separator+"person.ser");
ObjectOutputStreamoos=null;
//装饰流(流)
oos=newObjectOutputStream(newFileOutputStream(file));
//实例化类
Personper=newPerson("张三",30);
oos.writeObject(per);
//把类对象序列化
oos.close();
}
}
需要注意的是:
静态成员是不能被序列化的,因为静态成员是随着类的加载而加载的,与类共存亡,并且静态成员的默认初始值都是0;就是说静态成员属于类级别的,所以不能序列化,序列化只是序列化了对象而已。