重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
一个简单的Java序列化的例子
创新互联公司是一家集网站建设,石嘴山企业网站建设,石嘴山品牌网站建设,网站定制,石嘴山网站建设报价,网络营销,网络优化,石嘴山网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
import java.io.*;
import java.util.*;
class Data implements Serializable { // 实现序列话接口
private int n;
public Data(int n) { this.n = n; }
public String toString() { return Integer.toString(n); }
}
public class Worm implements Serializable {
public static void main(String[] args)
throws ClassNotFoundException, IOException { // 序列话读入和写入Object可能会有这两个异常
// 将你要序列化的object,保留到一个文件中
Random rand = new Random();
Data d = new Data(rand.nextInt(10)); //构建你需要序列话的Object
System.out.println("d = " + d);
ObjectOutputStream out = new ObjectOutputStream(
new FileOutputStream("worm.out")); // 准备写入的文件
out.writeObject(d);
out.flush();
out.close(); // 执行到这里你可以看见worm.out这个文件,
// 以下的代码读出你刚刚写入Object
ObjectInputStream in = new ObjectInputStream(
new FileInputStream("worm.out")); // 读你刚刚写入的文件
Data d2 = (Data)in.readObject(); // 重新构建你刚刚写入的Object
System.out.println("d2 = " + d2); }
}
Java中的序列化是把Java对象转换为字节序列的过程,能够将一个实例对象的状态信息写入到一个字节流中,使其可以通过socket进行传输、或者持久化到存储数据库或文件系统中,然后在需要的时候通过字节流中的信息来重构一个相同的
dataset使用java的序列化方法:
1、一方面,试图把RemotingFormat设置为SerializationFormat.Binary来序列化DataSet。
2、另一方面,也可以简单的把那行代码注释起来,并且保持默认值SerializationFormat.xml。在这种情况下,该例子都是通过计算执行deserialize这样一个DataSet操作所需要的时间来做大致的性能估计。
压缩和序列化主要用在数据的存储和传输上,二者都是由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变量是没有用处的。
简单来说,如果你只是自己同一台机器的同一个环境下使用同一个JVM来操作,序列化和反序列化是没必要的,当需要进行数据传输的时候就显得十分必要。比如你的数据写到文件里要被其他人的电脑的程序使用,或者你电脑上的数据需要通过网络传输给其他人的程序使用,像服务器客户端的这种模型就是一种应用,这个时候,大家想想,每个人的电脑配置可能不同,运行环境可能也不同,字节序可能也不同,总之很多地方都不能保证一致,所以为了统一起见,我们传输的数据或者经过文件保存的数据需要经过序列化和编码等操作,相当于交互双方有一个公共的标准,按照这种标准来做,不管各自的环境是否有差异,各自都可以根据这种标准来翻译出自己能理解的正确的数据。
除了在持久化对象时会用到对象序列化之外,当使用RMI(远程方法调用),或在网络中传递对象时,都会用到对象序列化。实现序列化:
1 首先要把准备要序列化类,实现 Serializabel接口
import java.io.Serializable;
public class Person implements Serializable {
//本类可以序列化
private String name ;
private int age ;
public Person(String name,int age)
{
this.name = name ; this.age = age ;
}
public String toString()
{
return "姓名:" + this.name + ",年龄" + this.age ;
}
}
2 序列化
package org.lxh.SerDemo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream ;
public class ObjectOutputStreamDemo
{
//序列化
public static void main(String[] args) throws Exception
{
//序列化后生成指定文件路径
File file = new File("D:" + File.separator + "person.ser") ;
ObjectOutputStream oos = null ;
//装饰流(流)
oos = new ObjectOutputStream(new FileOutputStream(file)) ;
//实例化类
Person per = new Person("张三",30) ;
oos.writeObject(per) ;
//把类对象序列化
oos.close() ;
}
}
需要注意的是:
静态成员是不能被序列化的,因为静态成员是随着类的加载而加载的,与类共存亡,并且静态成员的默认初始值都是0;就是说静态成员属于类级别的,所以不能序列化,序列化只是序列化了对象而已。