对象的序列化与反序列化---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将数据从源(文件.内存.键盘.网络)读入到内存 中,形成了 ...
随机推荐
- json的键为变量而不是字符串时,怎么写?
看栗子 /* 首先你创建了一个window的属性叫b, 并给它赋值为'cccddd' * 然后你创建了一个对象"a", 声明了一个它的属性叫b, 并且给b赋值为6 * 注意第一行的 ...
- 360动态加载的Android插件框架
github地址:https://github.com/Qihoo360/DroidPlugin DroidPlugin 是360手机助手在Android系统上实现了一种新的插件机制:它可以在无需安装 ...
- 内连接INNER JOIN(三十四)
内连接INNER JOIN 一.连接 MySQL的SELECT语句.多表更新.多表删除语句中支持JOIN操作. 语法结构 二.数据表参照 table_reference tbl_name [[AS] ...
- Vim使用心得总结
基本快捷键 v 进入可视模式 i / a 光标前/后插入模式 I / A 行首/末插入模式 Crtl+c 进入命令模式 Crtl+v 进入块可视模式 Q 进入EX模式 gh 进入选择模式 u 撤销 U ...
- 关于IDEA无法完整显示项目文件结构
今天发现一个奇怪的问题,就是我从本地导入了文件,明明已经成功了,但是在我的项目结构里面就是不显示,然而点击目录, 又能打开相应的文件,如图所示: 其实这个打开的只是包文件,只需要如下图操作即可:
- Mirai僵尸网络重出江湖
近年数度感染数十万台路由器的僵尸网络程序Mirai,虽然原创者已经落网判刑,但是Mirai余孽却在网络上持续变种,现在安全人员发现,Mirai已经将焦点转向Linux服务器了. 安全公司Netcout ...
- Windows 操作系统与 .NET Framework
Windos 2000 在单位的机房里好不easy才找到一台安装 Windows 2000 Server SP4 操作系统的server.这台硕果仅存的server到本月底也要退役了. Windows ...
- UI标签库专题九:JEECG智能开发平台 Choose(选则操作标签)
1. Choose(选则操作标签) 1.1. 參数 属性名 类型 描写叙述 是否必须 默认值 hiddenName string 隐藏域的ID 否 null hiddenid string 隐藏 ...
- geotif格式的波段描述信息探究
作者:朱金灿 来源:http://blog.csdn.net/clever101 有时打开一些geotif文件,可以看到它的波段描述,但是它究竟存储在文件的什么位置呢?今天研究了一下,大致搞清了这个问 ...
- Oracle 11g win7 64位【桌面类 && 服务器类】安装过程
Oracle 11g win7 64位[桌面类 && 服务器类]安装过程 一.首先,根据自己的操作系统位数(32位或64位),到官网下载相应的安装程序,如下图所示. ...