对象的序列化与反序列化---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将数据从源(文件.内存.键盘.网络)读入到内存 中,形成了 ...
随机推荐
- n阶幻方问题
转载自:http://blog.csdn.net/fengchaokobe/article/details/7437767 目录 第一节 n阶幻方问题 第二节 由n阶幻方引发 ...
- java jframe关闭窗口
frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { i ...
- css3 实现动画效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Windows server 2016 解决“无法完成域加入,原因是试图加入的域的SID与本计算机的SID相同。”
使用克隆的系统时,加域是出现如下问题.“无法完成域加入,原因是试图加入的域的SID与本计算机的SID相同.” 问题原因:Windows使用SID来表示所有的安全对象(security principa ...
- Fastboot线刷“复活”之刷机心得(三)——错误处理
在刷机的过程中可能不会是一帆风顺的.至少我是这种,总是会遇到这样或者那样的问题,下面是我为大家总结一些问题和解决办法,希望能对大家有所帮助. 一.电量问题 刷机和系统更新有一个共同的前 ...
- 文件/文件夹权限设置命令chmod的具体使用方法
chmod是文件/文件夹权限设置的命令,在Linux中常常遇到.本博文下面总结chmod的具体使用方法. Linux/Unix的档案调用权限分为三级,即档案拥有者user.群组group.其它othe ...
- Tiling POJ 2506 【大数】
id=2506">http://poj.org/problem?id=2506 Description In how many ways can you tile a 2xn rect ...
- stl--vector 操作实现
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...
- 什么是CSS重置,有些什么作用?
CSS重置是什么? 简单的说就是重置浏览器的CSS默认属性. 为什么要重置它,有什么作用? 因为浏览器的品种很多,每个浏览器的默认样式也是不同的,比如<button>标签,在IE浏览器.F ...
- Codefroces Educational Round 26 837 C. Two Seals
C. Two Seals time limit per test 1 second memory limit per test 256 megabytes input standard input o ...