java流(二)
目录
1 ObjectOutputStream/ObjectInputStream的使用
2 序列化
3 具体序列化的过程
4 Externalizable的简易介绍
实现序列化的Person类
/**
* 测试序列化所用的类
*/
class Person implements Serializable {
private String username;
private transient String password; //反序列化
public Person(String username,String password) {
this.username = username;
this.password = password;
}
public String toString() {
StringBuffer str = new StringBuffer();
str.append("username=" + this.username+"\r\n");
str.append("password=" + this.password);
return str.toString();
}
}
注意 password字段使用了transient表示,该字段不实现序列化(即,读取这个类时这个字段的值恒定位null)
测试方法
public class SerializableTest2 {
public static void main(String args[]) throws IOException, ClassNotFoundException {
testObjectSeri();
testObjectInSeri();
}
public static void testObjectSeri() throws IOException {
Person person = new Person("测试", "java");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"));
oos.writeObject("字符串");
oos.writeObject(person);
oos.flush();
oos.close();
System.out.println("入参:"+"\r\n"+"字符串 "+"\r\n"+person.toString());
}
public static void testObjectInSeri() throws IOException,
ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"));
String str = (String) ois.readObject();
System.out.println(str);
Person person = (Person) ois.readObject();
ois.close();
System.out.println(person.toString());
}
}
执行结果
入参:
字符串
username=测试
password=java
字符串
username=测试
password=null
注意读取数据时要按照传入顺序转换成对应的对象类型。
我们再来详细的看一下,序列化的过程
改造一下Person类
class Person implements Serializable {
private String username;
private transient String password; //反序列化
public Person(String username,String password) {
this.username = username;
this.password = password;
}
public String toString() {
StringBuffer str = new StringBuffer();
str.append("username=" + this.username+"\r\n");
str.append("password=" + this.password);
return str.toString();
}
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
System.out.println("writeObject invoked");
}
private void readObject(java.io.ObjectInputStream in) throws IOException,
ClassNotFoundException {
System.out.println("readObject invoked");
}
private Object writeReplace() throws ObjectStreamException {
System.out.println("writeReplace invoked");
return this;
}
private Object readResolve() throws ObjectStreamException {
System.out.println("readResolve invoked");
return this;
}
}
继续使用上面的测试方法
执行结果
writeReplace invoked
writeObject invoked
入参:
字符串
username=测试
password=java
字符串
readObject invoked
readResolve invoked
username=null
password=null
序列化与反序列化的内部执行按照以下顺序
writeReplace --> writeObject
readObject --> readResolve
结论
当进行序列化的时候:
首先JVM会先调用writeReplace方法,在这个阶段,我们可以进行张冠李戴,将需要进行序列化的对象换成我们指定的对象. (入口)
跟着JVM将调用writeObject方法,来将对象中的属性一个个进行序列化,我们可以在这个方法中控制住哪些属性需要序列化.
当反序列化的时候:
JVM会调用readObject方法,将我们刚刚在writeObject方法序列化好的属性,反序列化回来.
然后在readResolve方法中,我们也可以指定JVM返回我们特定的对象(不是刚刚序列化回来的对象).
另外 Externalizable 和是一个有实际方法需要实现的interface,包括writeExternal和readExternal:
现在在person后面添加这2个方法
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
System.out.println("readExternal"); } public void writeExternal(ObjectOutput out) throws IOException {
System.out.println("writeExternal");
}
执行结果
writeReplace invoked
writeExternal//-----覆盖之前的方法被执行
入参:
字符串
username=测试
password=java
readExternal//-----覆盖之前的方法被执行
readResolve invoked
username=null
password=null
参考文章
http://www.cnblogs.com/xt0810/p/3642904.html
http://dovecat.iteye.com/blog/66044
http://blog.csdn.net/yakihappy/article/details/3979373
http://developer.51cto.com/art/200908/147650.htm
http://dusiguxia.blog.163.com/blog/static/55629316201162635435180/
java流(二)的更多相关文章
- 登堂入室——java流
——文章出自PeterYe,不得私自转载 我所知道的 java.io里面的[流],就仿佛太平洋里面的水一样,浩浩荡荡,横无际涯... -----2016/7/16--------公寓处记录------ ...
- Java流
流是一组有顺序的,有起点和终点的字节集合,是对传输数据的总称或抽象.即数据在两设备间的传输称为流,流的本质是传输数据,依据传输数据特性将流抽象为各种类,方便更直观的进行数据操作. 流的分类: 数据类型 ...
- java 流输出的一些问题
一.java流的控制首先要先准备一个文件,例如:File f = new File(d:/lol.txt); 二.可以使用如下指令创建流,用于不同的用途 1.FileInputStream,FileO ...
- java 生成二维码、可带LOGO、可去白边
1.准备工作 所需jar包: JDK 1.6: commons-codec-1.11.jar core-2.2.jar javase-2.2.jar JDK 1.7: commons-codec- ...
- 深入理解Java流机制(一)
一.前言 C语言本身没有输入输出语句,而是调用"stdio.h"库中的输入输出函数来实现.同样,C++语言本身也没有输入输出,不过有别于C语言,C++有一个面向对象的I/O流类库& ...
- java web 二维码生成
pom支持: <!-- 二维码支持包 start--> <dependency> <groupId>com.google.zxing</groupId> ...
- Java流式思想和方法引用
目录 Java流式思想和方法引用 1. Stream流 1.1 概述 传统集合的多步遍历代码 Stream的更优写法 1.2 流式思想的概述 1.3 获取流 1.4 常用方法 ①逐一处理:forEac ...
- Java EE : 二、图解 Cookie(小甜饼)
目录 Java EE : 一.图解Http协议 Java EE : 二.图解 Cookie(小甜饼) Java EE : 三.图解Session(会话) 概述 一.概述 二.详细介绍Cookie 传输 ...
- 利用JAVA生成二维码
本文章整理于慕课网的学习视频<JAVA生成二维码>,如果想看视频内容请移步慕课网. 维基百科上对于二维码的解释. 二维条码是指在一维条码的基础上扩展出另一维具有可读性的条码,使用黑白矩形图 ...
随机推荐
- HTML、CSS、JS、JQ速查笔记
一.HTML 1.编写html文件 a.格式 <!DOCTYPE html> <html> <head> <title>标题</title& ...
- help.hybris.com和help.sap.com网站的搜索实现
help.hybris.com 我使用help.hybris.com时,发现每次在搜索栏输入文字时,没有发出任何HTTP请求,那么这个自动完成的下拉框里的记录从哪里来的?我看了下实现,发现所有自动完成 ...
- Activiti学习记录(二)
1.初始化数据库 使用工作流引擎创建23张表 public class TestActiviti { /** * 使用代码创建工作流需要的23张表 */ @Test public void creat ...
- C#赋值运算符
一.C#赋值运算符 C#语言的赋值运算符用于将一个数据赋予一个变量.属性或者引用.数据可以是常量.变量或者表达式. 1. 简单赋值 “=”操作符被称为简单赋值操作符.在一个简单赋值中,右操作数必须为某 ...
- C# checked运算符
一.C# checked运算符 checked运算符用于对整型算术运算和显式转换启用溢出检查. 默认情况下,表达式产生的值如果超出了目标类型的范围,将会产生两种情况: ?常数表达式将导致编译时错误. ...
- 基于GMap.NET地图下载器的开发和研究
基于GMap.NET地图下载器的开发和研究 软件下载地址:https://pan.baidu.com/s/1ay0aOm3fiZ35vlfD8kFYFw 1.地图浏览功能 可以浏览谷歌地图.百度.ar ...
- js display, visible 区别
注意: display:none和visible:hidden都能把网页上某个元素隐藏起来,在视觉效果上没有区别,但是在一些DOM操作中两者有区别: display:none ---不为被隐藏的对象保 ...
- C++ 无限定名称查找
无限定名称查找 (关键字:懒惰,挑捡,using指令的特殊性) 无限定名称查找实际上就是指没有限定(名称空间和名称空间运算符)名存在的一个名字的出现,其中对于using指令,其内部包含的所有的声明是被 ...
- 2019 ACM-ICPC全国邀请赛(西安) M.Travel 二分+判联通
https://nanti.jisuanke.com/t/39280 讲道理这题写bfs求最大边权限制下从1到n的最短步数,然后二分判一下就行了. 然鹅我还是直接套了dij,一开始纠结dij能不能过, ...
- Java 对数组的筛选
在Java里面 一般对一个数组进行筛选,去剔除一些元素,一般做法是用临时数组来存储,把符合条件的元素加入到新数组中,虽然数组有移除的方法但是 是线程不安全的: 而用迭代器Iterator,可以在遍历的 ...