`
中国爪哇程序员
  • 浏览: 167566 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

序列化(三) 实例分析深入了解序列化

    博客分类:
  • java
阅读更多
一.什么是序列化和反序化
对象的序列化是把对象写到一个输出流中。反序列化从这把输入流读取一个对象。

二。为什么要序列化
(1) 把对象持久化到一个文件中。像我们在做单元测试的时候,对于构造好的数据,可以持久化到文件中,这样就不用再从数据库中读取,在数据库中的测试数据很容易被人篡改。
(2) 像RMI,SOCKET,HESSION 等进行网络传输对象的场合,要把对象转成流的形式传递给客户端。而客户端对于取的流(byte[])要进行反序列化。

三。如何进行序列化
实现Serializable 接口

四。Serializable的作用
序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致 InvalidClassException。可序列化类可以通过声明名为 "serialVersionUID" 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)显式声明其自己的 serialVersionUID:

五。Serializable的使用说明
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
如果可序列化类未显式声明 serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认 serialVersionUID 值,如“Java(TM) 对象序列化规范”中所述。不过,强烈建议 所有可序列化类都显式声明 serialVersionUID 值,原因是计算默认的 serialVersionUID 对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的 InvalidClassException。因此,为保证 serialVersionUID 值跨不同 java 编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值。还强烈建议使用 private 修饰符显示声明 serialVersionUID(如果可能),原因是这种声明仅应用于直接声明类 -- serialVersionUID 字段作为继承成员没有用处。数组类不能声明一个明确的 serialVersionUID,因此它们总是具有默认的计算值,但是数组类没有匹配 serialVersionUID 值的要求。

六。实例说明

序列化对象
import java.io.Serializable;

public class Customer implements Serializable{

	private static final long serialVersionUID = 1L;
	private Long userId;
	private String name;
	private String password;
	private int age;
	
	public Long getUserId() {
		return userId;
	}
	public void setUserId(Long userId) {
		this.userId = userId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}



测试代码:

	public static void main(String[] args) throws Exception {

		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:/objectFile.obj"));

		//创建对象
		Customer customer = new Customer();
		customer.setUserId(1L);
		customer.setName("张三");
		customer.setPassword("123");
		customer.setAge(10);
		
		// 序列化对象
		out.writeObject("你好!");
		out.writeObject(new Date());
		out.writeObject(customer);
		out.writeInt(123); // 写入基本类型数据
		out.close();

		// 反序列化对象
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:/objectFile.obj"));
		System.out.println("obj1=" + (String) in.readObject());
		System.out.println("obj2=" + (Date) in.readObject());
		Customer obj3 = (Customer) in.readObject();
		System.out.println("obj3=" + obj3);
		System.out.println("userId :"+obj3.getUserId());
		System.out.println("name :"+obj3.getName());
		System.out.println("password :"+obj3.getPassword());
		System.out.println("age :"+obj3.getAge());
		int obj4 = in.readInt();
		System.out.println("obj4=" + obj4);
		in.close();

	}


输出内容:
obj1=你好!
obj2=Thu Jun 23 23:26:11 CST 2011
obj3=user.Customer@c20e24
obj4=123

如果Customer去掉implements Serializable
则会抛出异常:
Exception in thread "main" java.io.NotSerializableException: user.Customer
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at demo.Demo1.main(Demo1.java:28)
只有实现seriliable接口才可以进行序列化

先序列化对象,并保存。
在返序列化的时候,修改
	private static final long serialVersionUID = 2L;

则会抛异常:
Exception in thread "main" java.io.InvalidClassException: user.Customer; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1583)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at demo.Demo1.main(Demo1.java:36)
原因就是serialVersionUID 有校验版本兼容性的作用。

七 transient 关键字
对于一些比较敏感信息,不希望被反序化,如password,可以加上transient ,则不会被反序列。其他未加transient属性信息都会正常序列化和反序化。

八 writeObject 和 readObject
像ObjectOutputStream和ObjectInputStream 两个类提供了序列化和反序列化的方法。当然也可以自己重写这两个方法。自己定义序列化和反序列化,这往往涉及一些加密和解密算法,记得大学有一门课程“信息论”的一门课程,提到了一系列加密算法,可以序列化产生的流做处理,保证网络传输的安全性。

分享到:
评论

相关推荐

    通过实例深入了解java序列化

    本文将通过实例深入了解 Java 序列化,分析一些真实情境,帮助读者轻松牢记 Java 序列化中的一些高级认识。 序列化 ID 问题 ---------------- 在 Java 序列化中,序列化 ID 是一个非常重要的一点。它决定了两个类...

    XML序列化与反序列化 实战

    XML序列化与反序列化是.NET框架中处理数据交换的重要技术,它允许我们将对象的状态转换为XML格式的数据,也可以将XML数据...通过理解和使用提供的代码,你可以深入了解XML序列化的工作原理,并将其应用到自己的项目中。

    序列化与反序列化经典例子

    在提供的压缩包文件"Serialize"中,可能包含了使用不同序列化库或方法的例子,通过分析这些代码,我们可以学习如何在实践中应用序列化和反序列化,进一步提升我们的编程技能。记得在处理这些示例时,不仅要关注代码...

    C#序列化和反序列化案例.rar

    通过学习和分析这个案例,开发者不仅可以了解C#的序列化和反序列化机制,还可以掌握如何在Windows Forms应用程序中使用控件来展示和交互数据。 总之,C#的序列化和反序列化是数据处理的重要部分,而这个案例提供了...

    C#序列化和反序列化

    要使用XML序列化,你需要创建一个XMLSerializer实例,并提供要序列化的类型或对象。 3. **JSON序列化** 随着Web服务的广泛使用,JSON已经成为一种流行的数据交换格式。C#提供了Json.NET库,它可以方便地进行JSON...

    XML序列化与反序列化整理文档(12套)

    输入XML文档,它会分析元素和属性,并创建相应的类定义,这大大简化了序列化和反序列化的准备工作。 4. **实例代码**: 提供的实例代码可能包含以下部分: - 创建可序列化类的定义,包括必要的属性和标记。 - ...

    C#中使用二进制和ProtoBuf分别进行序列化、反序列化、压缩、解压缩对比测试示例源码.zip

    首先,让我们深入了解一下二进制序列化。C#中的`System.Runtime.Serialization.Formatters.Binary.BinaryFormatter`类提供了一种默认的序列化方式,它将对象的状态转换为字节流。这种序列化方式简单易用,但生成的...

    TIA博途-序列化指令Serialize的具体使用方法示例.docx

    在工业自动化领域,TIA博途( Totally Integrated Automation Portal)是西门子提供的一款全面集成自动化软件,用于设计...这将有助于深入理解TIA博途中的序列化和反序列化机制,提高你在自动化项目中的数据处理能力。

    PHP常见的序列化与反序列化操作实例分析

    本文将深入探讨这两个概念,结合实例来分析PHP中如何使用`serialize()`和`unserialize()`函数。 **1. 序列化(Serialization)** 序列化是将变量(如数组、对象等)转换为字符串的过程。在PHP中,`serialize()`...

    序列化网络传输示例(tcp/ip)

    通过查看和分析这两个文件,我们可以更深入地了解如何在实际项目中应用序列化技术进行TCP/IP通信。 值得注意的是,序列化还涉及到安全性问题,如防止恶意代码通过序列化漏洞攻击系统。因此,在设计和实现序列化方案...

    序列化和反序列化

    序列化和反序列化是计算机科学中的重要概念,特别是在数据存储、网络通信和持久化对象等领域广泛应用。...通过学习和分析这些代码,我们可以深入理解序列化和反序列化的具体实现,并能灵活运用到自己的项目中。

    Bboss和xstream序列化反序列化性能对比1

    在本文中,我们将深入探讨Bboss和Xstream两个序列化和反序列化库在性能方面的差异。这两个库在Java开发中广泛用于将对象转换为XML格式,以便于存储、传输或持久化。以下是对这两个库的详细分析。 首先,Bboss和...

    Java序列化和反序列化

    ### Java序列化与反序列化的深入解析 #### 序列化的功能与意义 序列化是Java编程语言中的一项核心功能,其主要目的是将对象的状态转换为可以存储或传输的格式,便于持久化保存或网络传输。序列化并不涉及对象的...

    反序列化代码……备忘一下……

    2. **源码分析**:博主可能详细讲解了反序列化的源码实现,包括如何读取字节流,解析数据结构,并重建对象实例。这可能涉及到反射、类型判断以及内存管理等概念。 3. **工具**:在处理反序列化时,可能会用到一些...

    c#序列化c#序列化

    通过以上分析,我们可以看到C#提供了一种强大而灵活的方式来处理对象的序列化和反序列化,这对于构建复杂的应用程序来说是非常有用的。无论是为了在不同进程间共享数据,还是为了持久化对象状态,C#的序列化功能都能...

    Java反序列化实战.pdf

    通过深入分析Fastjson和Weblogic的经典案例,我们可以看到,虽然反序列化技术在实际应用中带来了便利性和灵活性,但也伴随着一定的安全风险。因此,在设计和实现系统时,需要充分考虑安全性,采取有效的防御措施,...

    .net 序列化 和反序列化 Demo

    .NET 序列化和反序列化是.NET框架中非常重要的概念,它们在数据持久化、网络通信、跨进程通信等...通过运行和分析`SerializerDemo`中的代码,你可以更深入地了解每种序列化技术的优缺点,以及在特定场景下的适用性。

Global site tag (gtag.js) - Google Analytics