对象的序列化,反序列化

对象的序列化:

就是将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学习笔记(四)的更多相关文章

  1. Java IO学习笔记四:Socket基础

    作者:Grey 原文地址:Java IO学习笔记四:Socket基础 准备两个Linux实例(安装好jdk1.8),我准备的两个实例的ip地址分别为: io1实例:192.168.205.138 io ...

  2. Java IO学习笔记四

    内存操作流 之前的所有的流操作都是针对文件的,但是有时候只是想要实现数据间转换,此时如果我们想要创建一个文件然后再删除文件,那样显得有点麻烦,因此此时的内存操作流就显得很适合这类的操作,因为它只是在内 ...

  3. 【Java IO流】对象的序列化和反序列化

    对象的序列化和反序列化 1)对象序列化,就是将Object对象转换成byte序列,反之叫对象的反序列化. 2)序列化流(ObjectOutputStream),是字节的过滤流—— writeObjec ...

  4. 第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 ...

  5. Java对象的序列化和反序列化[转]

    Java基础学习总结--Java对象的序列化和反序列化 一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化.把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用 ...

  6. (记录)Jedis存放对象和读取对象--Java序列化与反序列化

    一.理论分析 在学习Redis中的Jedis这一部分的时候,要使用到Protostuff(Protobuf的Java客户端)这一序列化工具.一开始看到序列化这些字眼的时候,感觉到一头雾水.于是,参考了 ...

  7. java中对象的序列化和反序列化

    [对象的序列化和反序列化 ] 1.定义:序列化--将对象写到一个输出流中.反序列化则是从一个输入流中读取一个对象.类中的成员必须是可序列化的,而且要实现Serializable接口,这样的类的对象才能 ...

  8. Java对象的序列化与反序列化

    序列化与反序列化 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程.一般将一个对象存储至一个储存媒介,例如档案或是记亿体缓冲等.在网络传输过程中,可以是字节或是 ...

  9. Java IO学习笔记:概念与原理

    Java IO学习笔记:概念与原理   一.概念   Java中对文件的操作是以流的方式进行的.流是Java内存中的一组有序数据序列.Java将数据从源(文件.内存.键盘.网络)读入到内存 中,形成了 ...

随机推荐

  1. idea+maven+springmvc

    黑了Java这么多年, 今天为Java写一篇文章吧. 这篇文章主要是想帮助那些刚接触到Java, 同时想从事Java WEB GUI开发的人. 对我而言, 我很早就有想尝试用Java写WEB的想法, ...

  2. jquery基本Dom操作

    1 html()获取所有的html内容 2 html(value) 设置html内容,有html自动解析 3 text() 获取文本内容 4 text(value) 设置文本内容,有html自动转义 ...

  3. Java基础算法

    i++;++i; i--;--i; int a=5;int b=a++;++放在后面,表示先使用a的值,a再加1b=5,a=a+1,a=6 int c=5;int d=++c;++放在前面,表示先将c ...

  4. 请允许我成为你的夏季——shiro、jdbcInsertall

    这两天总是觉得自己被关进了一个大笼子,日子拮据.生活不就是这样吗,一边觉得自己很差劲,一边又想成为一个更好的自己.可那又有什么办法呢,万物皆有裂痕,但那又怎样,那是光照进来的地方啊. 开始学习shir ...

  5. JavaScript进阶之执行上下文和执行栈

    js引擎的执行过程 执行上下文和执行栈属于js引擎的执行过程的预编译阶段. 执行上下文(Execution Context) 执行上下文是当前 JavaScript 代码被解析和执行时所在环境的抽象概 ...

  6. Yum数据库错误

    使用yum时提示数据库错误: /var/lib/rpm... open... db4 error from db->close:... 解决办法: 1.删除/var/lib/rpm目录下的__d ...

  7. Unityclient通信測试问题处理(一)

    Unityclient通信測试问题处理(一) 近期在測试程序的通信模块时.遇到了一个问题:Unity的API函数仅仅能在主线程中调用.而作为client程序,我单独启用了一个监听线程来接收服务端发送的 ...

  8. 游戏开发之UDK引擎介绍和模型导入

    2014-09-18 10:01:3 3.7.5" style="border:0px; vertical-align:middle; max-width:100%"&g ...

  9. 内网使用 IPV6 之 Chrome 浏览器 扩展程序 篇

    手机端的 Google Chrome 浏览器在打开 "流量节省程序"后,它会通过 Google 的服务器中转流量,这台服务器支持 IPV4 和 IPV6.想在PC端使用类似的&qu ...

  10. VB&XML的增删改查

    简介:XML的增删改查 开发过程中有许多后台操作XML的过程,每次需要操作时都是找很多代码来参考或者百度一下.今天决定补充下XML操作的知识,把XML操作的增删改查都写了一遍,供以后开发参考 查询: ...