对象的序列化与反序列化---IO学习笔记(四)
对象的序列化,反序列化
对象的序列化:
就是将Object转换成byte序列
对象的反序列化:
将byte序列转换成Object
序列化流。反序列化流
序列化流(ObjectOutputStream),是字节的过滤流—>主要方法:writeObject()
反序列化流(ObjectInputStream)—>主要方法:readObject()
序列化接口(Serializable)
对象必须实现序列化接口。才干进行序列化。否则将出现异常
这个接口,没有不论什么方法,仅仅是一个标准。
主要的对象序列化的操作:
student实体类:
package com.test.ObjectInputStream;
import java.io.Serializable;
public class Student implements Serializable{
private String name;
private int age;
private String sex;
public Student(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}
对象序列化与反序列化操作类:
package com.test.ObjectInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class ObjectInputStreamTest {
public static void main(String[] args) throws IOException {
String filename = "C:\\Users\\Administrator\\Desktop\\javaIO\\測试ObjectOutputStream的文件.txt";
// //1.对象的序列化
// ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename));
// Student stu = new Student("小灰灰", 22, "男");
// oos.writeObject(stu);
// oos.flush();
// oos.close();
//2.对象的反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename));
try {
Student stu1 = (Student) ois.readObject();
System.out.println(stu1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
ois.close();
}
}
结果截图:
上边的样例是:先通过对象的序列化把对象序列化的内容写入到文件里,然后在通过对象的反序列化从文件里再把对象序列化的内容读取出来。
注意:须要使用序列化的地方:网络传输对象数据时
transient关键字的使用:
当student实体类中name属性前加入transient修饰的时候,那么该属性不会进行jvm默认的序列化,也能够自己完毕这个属性的序列化。
那么上边程序的执行结果为:
事实上查看ArrayList类的源代码:
ArrayList类实现了序列化接口:
ArrayList中的元素数据的数组使用了transient关键字修饰:
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
ArrayList中的readObject()方法
/**
* Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
* deserialize it).
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
elementData = EMPTY_ELEMENTDATA;
// Read in size, and any hidden stuff
s.defaultReadObject();
// Read in capacity
s.readInt(); // ignored
if (size > 0) {
// be like clone(), allocate array based upon size not capacity
ensureCapacityInternal(size);
Object[] a = elementData;
// Read in all elements in the proper order.
for (int i=0; i<size; i++) {
a[i] = s.readObject();
}
}
}
ArrayList中的writeObjct()方法:
/**
* Save the state of the <tt>ArrayList</tt> instance to a stream (that
* is, serialize it).
*
* @serialData The length of the array backing the <tt>ArrayList</tt>
* instance is emitted (int), followed by all of its elements
* (each an <tt>Object</tt>) in the proper order.
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject();
// Write out size as capacity for behavioural compatibility with clone()
s.writeInt(size);
// Write out all elements in the proper order.
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
ArrayList类中的元素数据数组为什么要用transient关键字修饰呢?
原因:
并非不想被序列化,而是自己实现了自己的序列化和反序列化的操作来提高性能。由于ArrayList并不能确定数据元素的个数。所以用transient关键字修饰的根本原因是把数组中的有效元素做序列化。无效元素就不进行序列化了,这样能够提高性能。
序列化中子类和父类构造函数的调用问题
两个问题:
(1)一个类实现了序列化的接口,那么它的子类都能够进行序列化。
(2)对子类对象进行反序列化操作的时候,假设其父类没有实现序列化接口。那么其父类的构造函数会被显式调用。
package com.test.ObjectInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectSerialTest {
public static void main(String[] args) {
String filename = "C:\\Users\\Administrator\\Desktop\\javaIO\\測试序列化调用问题的文件.txt";
try {
// WriteObject(filename);
ReadObject(filename);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void WriteObject(String filename) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
filename));
Person3 person3 = new Person3();
oos.writeObject(person3);
oos.flush();
oos.close();
}
public static void ReadObject(String filename) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
filename));
Person1 person = (Person1) ois.readObject();
System.out.println(person);
ois.close();
}
}
class Person1 {
public Person1() {
System.out.println("person1");
}
}
class Person2 extends Person1 implements Serializable {
public Person2() {
System.out.println("person2");
}
}
class Person3 extends Person2 {
public Person3() {
System.out.println("person3");
}
}
结果截图:
上边的代码当更改为Person3的两个父类都没有实现序列化接口,而是仅仅有Person3实现了序列化接口时,反序列化就会产生这种结果(如图)。
,所以通过上边的样例就能够知道第二个问题的结论。
对象的序列化与反序列化---IO学习笔记(四)的更多相关文章
- Java IO学习笔记四:Socket基础
作者:Grey 原文地址:Java IO学习笔记四:Socket基础 准备两个Linux实例(安装好jdk1.8),我准备的两个实例的ip地址分别为: io1实例:192.168.205.138 io ...
- Java IO学习笔记四
内存操作流 之前的所有的流操作都是针对文件的,但是有时候只是想要实现数据间转换,此时如果我们想要创建一个文件然后再删除文件,那样显得有点麻烦,因此此时的内存操作流就显得很适合这类的操作,因为它只是在内 ...
- 【Java IO流】对象的序列化和反序列化
对象的序列化和反序列化 1)对象序列化,就是将Object对象转换成byte序列,反之叫对象的反序列化. 2)序列化流(ObjectOutputStream),是字节的过滤流—— writeObjec ...
- 第12讲-Java中的IO操作及对象的序列化与反序列化
1.知识点 1.1.课程回顾 1.2.本章重点 1.2.1 io操作 1.2.2 对象的序列化与反序列化 2.具体内容 2.1.Java IO 2.1.1.什么是IO IO其实就是输入.输出 I ...
- Java对象的序列化和反序列化[转]
Java基础学习总结--Java对象的序列化和反序列化 一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化.把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用 ...
- (记录)Jedis存放对象和读取对象--Java序列化与反序列化
一.理论分析 在学习Redis中的Jedis这一部分的时候,要使用到Protostuff(Protobuf的Java客户端)这一序列化工具.一开始看到序列化这些字眼的时候,感觉到一头雾水.于是,参考了 ...
- java中对象的序列化和反序列化
[对象的序列化和反序列化 ] 1.定义:序列化--将对象写到一个输出流中.反序列化则是从一个输入流中读取一个对象.类中的成员必须是可序列化的,而且要实现Serializable接口,这样的类的对象才能 ...
- Java对象的序列化与反序列化
序列化与反序列化 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程.一般将一个对象存储至一个储存媒介,例如档案或是记亿体缓冲等.在网络传输过程中,可以是字节或是 ...
- Java IO学习笔记:概念与原理
Java IO学习笔记:概念与原理 一.概念 Java中对文件的操作是以流的方式进行的.流是Java内存中的一组有序数据序列.Java将数据从源(文件.内存.键盘.网络)读入到内存 中,形成了 ...
随机推荐
- nyoj--19--擅长排列的小明(dfs)
擅长排列的小明 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 小明十分聪明,而且十分擅长排列计算.比如给小明一个数字5,他能立刻给出1-5按字典序的全排列,如果你想为难 ...
- Alternating Sum
http://codeforces.com/problemset/problem/963/A 不考虑正负的话,每两项之间之间公比为b/a,考虑正负,则把k段作为循环节,循环节育循环节之间公比为(b/a ...
- ubuntu server 网络配置,主机名配置
一.通过命令ifconfig -a 查看可用网络设备 通过上面的命令,本机可用的网络设备为enp4s0f0 和enp4s0f1 ,不同的系统版本和硬件配置网络设备名可能不一样,所以一定要先确认本机可用 ...
- js预编译和函数执行
javascript 执行过程 1.语法检测(有没有基本的语法错误,例如中文,关键字错误...)2.词法分析(预编译) (1)创建全局GO(global object)对象 (2)对var声明的变量进 ...
- python 爬虫使用
python爬虫架构 Python 爬虫架构主要由五个部分组成,分别是 调度器.URL管理器.网页下载器.网页解析器.应用程序. 调度器:相当于一台电脑的CPU,主要负责调度URL管理器.下载器.解析 ...
- 【Oracle】使用bbed恢复delete的数据
表中的数据被delete之后并不会真正删除数据,而是打了一个删除标记,仅仅要还没有被覆盖就能够恢复回来. 实验步骤例如以下: SYS@ORCL>create table bbed_test(x ...
- MyReport.Form表单引擎
MyReport.Form表单引擎.主要提供表单模板的设计以及表单模板的预览填报等功能集合. 支持文本框.选择框.数字框.日期框.图片框.组合框.弹出框等经常使用控件. watermark/2/tex ...
- Eclipse上开发IBM Bluemix应用程序
林炳文Evankaka原创作品. 转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要解说了怎样使用安装EclipseIBM Bluemix插件.并在Eclipse ...
- 70.nodejs操作mongodb
转自:https://www.cnblogs.com/whoamme/p/3467374.html 首先安装nodejs mongodb npm install mongodb var mongodb ...
- 关于vuex的项目中数据流动方式
vue的核心是数据驱动,所有数据变更的时机很重要,也就是watch的内容,一般是数据逻辑的操作.在使用vuex的项目中,我们在vuex中只是发请求.拿数据,在视图中来进行逻辑的操作.数据的更新. 1. ...