小马SCJP认证讲坛---序列化与反序列化
发布: 2010-4-08 16:51 | 作者: mawl | 来源: 迈胜 IT人才培训机构
原题在现:
11.jpg
考察点:对象序列化与反序列化
解析:首先需指出的是题目的Realizable应换为Readable。
A选项的大意是:聚合类实例化的对象不能被序列化。(什么叫聚合,即has-a关系,如果说,类A聚合类B,意味着类A包含类B的对象。)
B选项的大意是:在一架虚拟机上序列化的对象能够被成功的在另外一台虚拟机上反序列化
C选项的大意是:用volatile修饰的对象无法成功的序列化和反序列化。
D选项的大意是:用transient修饰的对象无法成功的序列化和反序列化。明显这句话是正确的。
E选项的大意是:一个父类没有实现Serialization接口的子类对象进行序列化是合法的。
帮大家把大意翻译出来,相信答案就很明显了。
扩展:序列化与反序列化的的几个关键知识点:
1、什么是序列化、反序列化
Serialization(序列化)是一种将对象以一连串的字节描述的过程;
反序列化deserialization是一种将这些字节重建成一个对象的过程。
2、为什么要序列化
Java中,一切都是对象,在分布式环境中经常需要将Object从这一端网络或设备传递到另一端。这就需要有一种可以在两端传输数据的协议。Java序列化机制就是为了解决这个问题而产生的。
3、什么是serialVersionUID
Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。
当实现java.io.Serializable接口的实体(类)没有显式地定义一个名为serialVersionUID,类型为long的变量时,Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,只有同一次编译生成的class才会生成相同的serialVersionUID 。
4、怎么样进行一个简单的序列化反序列化过程
代码演示如下:
用来序列化的一个用户类:UserInfo.java
CODE:
package com.mison.serialize;
import java.io.Serializable;
public class UserInfo implements Serializable{
private String username;
private String password;
private transient int age;
public UserInfo(String username,String password,int age){
this.age = age;
this.password = password;
this.username = username;
}
public String toString(){
return "用户名:"+ this.username + ";密码:" + this.password + ";年龄:" + this.age ;
}
}
实现序列化与反序列化的主函数类:TestSerializeable.java
CODE:
package com.mison.serialize;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
public class TestSerializeable {
//序列化对象到文件
public static void serialze(String filename){
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename));
out.writeObject("序列化日期是:");//序列化一个字符串到文件
out.writeObject(new Date());//序列化一个日期到文件
UserInfo user = new UserInfo("mawl","马文亮",25);
out.writeObject(user);//序列化一个对象
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("系统文件找不到。");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void deserialize(String filename) throws ClassNotFoundException{
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename));
String time = (String)in.readObject();
System.out.println(time.toString());
Date d = (Date)in.readObject();
System.out.println(d.toString());
UserInfo user = (UserInfo)in.readObject();
System.out.println(user.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("系统找不到文件");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
serialze("e:\\text.txt");
System.out.println("序列化完毕");
try {
deserialize("e:\\text.txt");
System.out.println("反序列化完毕");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
有关例子的注意点:
1、序列化时用transient修饰的变量不会被序列化
2、如果你先序列化对象A后序列化B,那么在反序列化的时候一定记着JAVA规定先读到的对象是先被序列化的对象,不要先接收对象B,那样会报错
3、针对对象的序列化,都保存了什么内容:
1)对象的类型
2)对象属性的类型
3)对象属性的值
(关于这点你可以用以上的例子,对text.txt这个文件的大小来判断)
hjqhezgh2010-4-09 09:30:32
恩。。学习了。。我有个疑问问下。。
如果我有这么一个类的关系
CODE:
public class A{
private B b;
}
public class B{
}
我要序列化A,但是B是没有实现序列化接口的,那么结果会是什么呢。
mawl2010-4-09 10:31:57
回复 2# hjqhezgh
这个问题问得好,强总是能问到点儿上啊。针对这个问题我要做以下几点说明:
1、首先你这是一个关联的情况。聚合在某些情况下也是可以被序列化的。所以题目的A答案是不正确的。(但是,这只是针对当前这个类,也就是你问的A这个类)
java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的“深复制”,即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。
2、如果上面那个观点比较抽象的话, 我们可以做一个实际的例子。就用我上面的例子,不同的是我们增加一个B类。在UserInfo里加一个成员变量:private B b;然后我们以两种情况跑跑看。第一种我们不注释private B b。然后我们会发现text.txt文件的大小是213字节。在打开这个.txt文档看看。我们在乱码文字里可以看到:com/mison/serialize/B;这样一串字符串。这则说明没有明确申明Serializable的类B创建的这个引用b也被序列化了。第二种情况则是,我们把private B b;这段代码给注释以后,在运行我们的主函数类。会发现text.txt类变为182字节。缺少的那部分正是B这个类创建的引用值b的序列化的内容。
3、同样。这才是问题的关键。为了应证B这个类有没有被序列化亦或是能不能被序列化。我们还可以多做一点测试。我们在B这个类里面加一个属性值
private int age;然后我们在运行一个主函数这个类。这时我们会发现text.txt的这个文件的大小还是213字节。这就说明B这个类没有被序列化。反过来说,这就说明被序列化的也就只是UserInfo这个类的成员变量b 这个引用值。说白点就只是序列化了一个引用对象的地址。既然进行到这步,我们肯定会在做一个测试。那就是我们在创建这个b的引用的时候直接给它new一个内存空间会怎么样?(这个你不妨可以试试看)它会抛一个java.io.NotSerializableException: com.mison.serialize.B 的错误。这下答案很明显了。进一步说明了,B类不能被实例化。
分享到:
相关推荐
在***中处理JSON的序列化和反序列化是Web开发中常见的需求。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,由于其简洁性和易于阅读性,被广泛用于服务器与客户端之间的数据传输。下面将详细介绍**...
本篇文章将深入探讨C++中JSON的序列化与反序列化。 **一、JSON序列化** 序列化是指将C++的对象转换为JSON字符串的过程,以便在网络上传输或保存到文件中。常见的C++ JSON序列化库有RapidJSON、nlohmann/json、...
Java对象的序列化和反序列化是Java编程中一项重要的技术,主要用于将对象的状态转换为字节流,以便存储或在网络上传输。这一过程对于理解Java的IO操作、持久化数据以及实现分布式通信等场景非常关键。 首先,我们来...
XML序列化与反序列化是.NET框架中处理数据交换的重要技术,它允许我们将对象的状态转换为XML格式的数据,也可以将XML数据恢复为等效的对象。这个实战项目专注于使用C#实现这一过程,使得开发者能够方便地在XML文件和...
在编程领域,序列化和反序列化是两个关键的概念,它们用于将对象的状态转换为可存储或可传输的格式,然后在需要时恢复为原始对象。Boost库提供了一个强大的工具——Boost.Serialization,来帮助程序员实现这个功能。...
在编程领域,序列化和反序列化是两个关键的概念,特别是在跨平台通信、持久化存储以及数据传输中扮演着重要角色。本篇文章将深入探讨C#和Java中的序列化与反序列化机制。 首先,我们要了解什么是序列化。序列化是指...
在编程领域,序列化和反序列化是两个关键的概念,特别是在数据存储、网络传输和对象持久化等场景中。它们允许我们将对象的状态转换为字节流(序列化),然后在需要的时候将字节流还原为原来的对象(反序列化)。在C#...
在IT领域,序列化和反序列化是两个关键的概念,特别是在数据存储、网络通信和分布式系统中。它们涉及将对象的状态转换为可持久化的格式(序列化),以及将这种格式还原回原来的对象(反序列化)。本文将深入探讨这两...
### Java序列化(Serializable)的作用与反序列化详解 #### 一、序列化的概念 序列化是指将程序中的对象转换为一系列字节流的过程,主要用于保存对象的状态或在网络之间传输对象。序列化的主要目的是为了能够持久化...
Jackson是Java领域中广泛使用的JSON处理库,它提供了高效的JSON序列化和反序列化功能。在Java应用程序中,我们经常需要将Java对象转换为JSON字符串(序列化)或从JSON字符串恢复Java对象(反序列化),Jackson库就是...
在C#编程中,序列化和反序列化是两个关键的概念,它们主要用于对象状态的持久化和恢复。本文将深入探讨C#中的XML序列化和反序列化技术,包括如何将XML文档解析为对象,以及如何将对象转换回XML文档进行存储。我们将...
在IT领域,序列化和反序列化是两个关键的概念,特别是在网络通信、数据持久化以及对象存储中。本文将深入探讨Hessian框架的基础知识,它是一个高效的二进制序列化协议,广泛应用于Java和.NET之间跨语言通信。通过...
在Unity游戏引擎中,开发人员经常需要处理数据的序列化和反序列化,以便于存储、传输或网络通信。Protocol Buffers(Protobuf)是一种高效、跨平台的数据序列化协议,由Google开发。本Demo将展示如何在Unity中集成并...
反序列化是将JSON格式的字符串转换为程序可直接使用的对象的过程,这对于处理网络请求返回的数据至关重要。在本篇文章中,我们将深入探讨JSON反序列化的概念、原因以及在实际开发中的应用。 一、什么是JSON反序列化...
protobuf序列化和反序列化技术是大数据处理领域中不可或缺的一部分,尤其在实时大数据场景下,高效的数据传输和存储对性能有着直接影响。谷歌推出的Protocol Buffers(简称protobuf)是一种语言无关、平台无关的数据...
Java反序列化是一种将已序列化的对象状态转换回对象的过程,它是Java平台中持久化数据的一种常见方式。在Java应用程序中,序列化用于保存对象的状态以便稍后恢复,或者在网络间传输对象。然而,这个过程也可能引入...
本主题将深入探讨如何在Windows Forms(WF)环境中,利用C#语言进行对象的直接保存与读取,以及通过对象序列化和反序列化的方式实现对象的保存与恢复。 首先,我们来理解什么是对象的直接保存与读取。在C#中,可以...
本教程将详细讲解如何在C#中实现`TreeView`控件的序列化和反序列化,这对于数据持久化和用户界面状态的保存至关重要。 首先,让我们了解序列化和反序列化的基本概念。**序列化**是将对象的状态转换为可存储或传输的...
在编程领域,序列化是一种将对象的状态转换为可存储或可传输的形式的过程。这通常用于持久化数据,即保存对象的状态以便稍后恢复,或者在网络间传输对象。在这个主题“序列化窗体所有控件”中,我们主要关注的是如何...
在C#编程语言中,数组和序列化是两个非常重要的概念。数组是数据结构的基础,序列化则是数据传输和持久化的关键技术。接下来,我们将深入探讨这两个主题。 **数组** 数组是C#中用于存储固定数量同类型元素的集合。...