java序列化(二)
上一篇我们简单的了解了java的序列化方法。可以想一下,如果有两个类,如果父类实现了序列化,子类没有实现序列化,子类在进行对象序列化读写时,父类和子类均被实现序列化。如果其中父类没有实现序列化,子类实现了序列化,那么序列化和反序列化会发生什么情况呢?大胆猜测一下,父类没有经过序列化,所以他的属性不会被保留下来,在反序列化时应该没值。下面分两种情况验证一下。
第一种是父类无空参构造函数
package serializable.testone; /**
* @Description: 未实现序列化的父类
* @Author: haoqiangwang3
* @CreateDate: 2020/1/3
*/
public class Biology {
public String type; private int num; /**
* 父类构造函数
* @param type
* @param num
*/
public Biology(String type, int num){
this.type = type;
this.num = num;
} public String getType() {
return type;
} public void setType(String type) {
this.type = type;
} public int getNum() {
return num;
} public void setNum(int num) {
this.num = num;
}
}
子类继承父类,并实现了序列化
package serializable.testone; import java.io.Serializable; /**
* @Description: 实现序列化的子类
* @Author: haoqiangwang3
* @CreateDate: 2020/1/3
*/
public class PeoPle extends Biology implements Serializable { public String name; protected String gender; private int age; /**
* 子类构造函数
* @param type
* @param num
* @param name
* @param gender
* @param age
*/
public PeoPle(String type, int num, String name, String gender, int age){
super(type,num);
this.name = name;
this.gender = gender;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getGender() {
return gender;
} public void setGender(String gender) {
this.gender = gender;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} }
最后测试一下结果
package serializable.testone; import java.io.*; /**
* @Description: 测试类
* @Author: haoqiangwang3
* @CreateDate: 2020/1/3
*/
public class TestOne {
public static void main(String[] args) throws IOException, ClassNotFoundException {
PeoPle peoPle = new PeoPle("human",10000,"张三","男",25); //序列化,写到文件中
FileOutputStream fos = new FileOutputStream("test.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(peoPle);
oos.flush();
oos.close(); System.out.println("序列化成功..."); //反序列化
FileInputStream fis = new FileInputStream("test.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
PeoPle p = (PeoPle)ois.readObject();
System.out.println("p.getType() = " + p.getType());
System.out.println("p.getNum() = " + p.getNum());
System.out.println("p.getName() = " + p.getName());
System.out.println("p.getGender() = " + p.getGender());
System.out.println("p.getAge() = " + p.getAge());
}
}
运行结果如下:
序列化成功...
Exception in thread "main" java.io.InvalidClassException: serializable.testone.PeoPle; no valid constructor
at java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(ObjectStreamClass.java:169)
at java.io.ObjectStreamClass.checkDeserialize(ObjectStreamClass.java:874)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2043)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at serializable.testone.TestOne.main(TestOne.java:26)
可以发现,序列化成功了,但是反序列化的时候发生了异常。
第二种,父类含有无参构造函数。
package serializable.testtwo; public class Person {
public String name; public String gender; public int age; float height; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getGender() {
return gender;
} public void setGender(String gender) {
this.gender = gender;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public float getHeight() {
return height;
} public void setHeight(float height) {
this.height = height;
}
}
子类如下
package serializable.testtwo; import java.io.Serializable; public class Male extends Person implements Serializable { private static final long serialVersionUID = 1L; public boolean beard; protected String weight; public boolean haveBeard(int age){ boolean flag = false;
if(age >= 18){
flag = true;
}
return flag;
} public boolean isBeard() {
return beard;
} public void setBeard(boolean beard) {
this.beard = beard;
} public String getWeight() {
return weight;
} public void setWeight(String weight) {
this.weight = weight;
}
}
测试类:
package serializable.testtwo; import java.io.*; public class TestTwo {
public static void main(String[] args) throws IOException, ClassNotFoundException { /**Male继承父类Person,自身实现序列化接口,其父类Person没有实现序列化接口*/
FileOutputStream fos = new FileOutputStream("male.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
Male male = new Male(); /** 父类属性赋值 */
male.setName("张三");
male.setGender("男");
male.setAge(25);
male.setHeight(175); /**其自身属性赋值*/
male.setBeard(true);
male.setWeight("150"); //序列化
oos.writeObject(male);
oos.flush();
oos.close(); //反序列化
FileInputStream fis = new FileInputStream("male.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Male ml = (Male) ois.readObject(); //结果打印
System.out.println("ml.getName() = " + ml.getName());
System.out.println("ml.getGender() = " + ml.getGender());
System.out.println("ml.getHeight() = " + ml.getHeight());
System.out.println("ml.getAge() = " + ml.getAge());
System.out.println("ml.isBeard() = " + ml.isBeard());
System.out.println("ml.getWeight() = " + ml.getWeight());
}
}
运行结果如下
ml.getName() = null
ml.getGender() = null
ml.getHeight() = 0.0
ml.getAge() = 0
ml.isBeard() = true
ml.getWeight() = 150
可以发现,序列化和反序列都没有报错,但是反序列化之后父类的属性值都没有。这也验证了我们之前的猜想。
总结一下:
1、非序列化的父类,其子类实现序列化时承担保存和恢复父类public、protected、package等子类可访问到子类的字段;
2、非序列化的父类,其子类进行序列化时,父类需要有用public或者protected修饰的空参构造函数;
3、若无空参构造函数的父类,其子类在运行序列化时将正常进行,但反序列化时会发生错误,并抛出异常。但父类有空参构造函数,子类完成序列化,父类属性却没有参与到序列化中。
其中还有其他稍微复杂的应用,在此就不多说了,详细可以看下此文章:https://mp.weixin.qq.com/s/Ta0vhFEZL2wGk2x1ES7HHg
java序列化(二)的更多相关文章
- Java 序列化和反序列化(二)Serializable 源码分析 - 1
目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 2. ObjectOutputStream 源码分析 2.1 ObjectOutputSt ...
- 理解Java对象序列化(二)
关于Java序列化的文章早已是汗牛充栋了,本文是对我个人过往学习,理解及应用Java序列化的一个总结.此文内容涉及Java序列化的基本原理,以及多种方法对序列化形式进行定制.在撰写本文时,既参考了Th ...
- Java序列化与反序列化
Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?本文围绕这些问题进行了探讨. 1.Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列 ...
- [转] Java序列化与反序列化
原文地址:http://blog.csdn.net/wangloveall/article/details/7992448 Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java ...
- Java序列化的几种方式以及序列化的作用
Java序列化的几种方式以及序列化的作用 本文着重讲解一下Java序列化的相关内容. 如果对Java序列化感兴趣的同学可以研究一下. 一.Java序列化的作用 有的时候我们想要把一个Java对象 ...
- Java学习笔记(十七)——java序列化
[前面的话] 做项目总是要用到很多东西,遇到一个新的知识,并不是这个知识出来的时间短,而是对于自己来说是新的,所以就需要自己去学习,希望今后可以提高学习的效率. 这篇文章是关于Java 序列化的,选择 ...
- java基础知识回顾之javaIO类--java序列化和反序列化
/** * * 一:理解序列化反序列化及其应用 * 序列化:把堆内存的对象转化成字节流的过程. * 反序列化:把字节流序列恢复重构成对象的过程. * 对象的序列化的用途:1.把对象的字节序列持久化, ...
- Java序列化接口的作用总结
一个对象有对应的一些属性,把这个对象保存在硬盘上的过程叫做”持久化”. 把堆内存中的对象的生命周期延长,存入硬盘,做持久化操作.当下次再需要这个对象的时候,我们不用new了,直接从硬盘中读取就可以了. ...
- Java序列化技术
Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化? Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象 ...
- java 序列化 serialVersionUID 的作用 和 两种添加方式
serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...
随机推荐
- 原生_H5交互插件(适用于与V2.1)
这是js代码 /* * 适合版本为 2.1.0 * 前提是url上加 from=app */ var Native = {}; var ua = navigator.userAgent; var oU ...
- HDU 1026 BSF+优先队列+记录路径、
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #inclu ...
- Spring Boot版本,Spring Cloud版本与组件版本关系
我们在学习Spring Cloud时,可能总是碰到以下问题: 1.Spring Boot版本与Spring Cloud版本关系 2.启动时,报莫名其妙的错,稀里糊涂的换个版本就好了 3.这么多版本,用 ...
- MATLAB常用函数, 常见问题
MATLAB常用函数 1.常用取整函数 round(x):四舍五入函数 floor(x) : 向下取整, 即 floor(1.2)=1, floor(1.8) = 1 ceil(x) : 向上取整, ...
- hsqldb使用
1 hsqldb介绍 HyperSQL DataBase 是一个现代的关系数据库管理软件,比较彻底遵从SQL:2008标准和JDBC4规范.支持SQL:2008标准所以的核心特性和很多的可选特性. H ...
- CodeForces 825G"Tree Queries"(选根建树)
传送门 •参考资料 [1]:CodeForces 825G Educational Round #25 G :建树选根大法+O1大法+iostream解绑了还是慢 •题意 给定一颗包含 n 个节点的树 ...
- 常用mime.types
以下是从nginx配置文件mime.types中提取出的最常用的文件格式, 整理了下, 方便查看 类型 文件格式 default_type application/octet-stream - tex ...
- @RequestBody、@ResponseBody注解是如何将输入输出转换成json的
@RequestBody.@ResponseBody注解,可以直接将输入解析成Json.将输出解析成Json,但HTTP 请求和响应是基于文本的,意味着浏览器和服务器通过交换原始文本进行通信,而这里其 ...
- 2018-8-10-win10-uwp-商业游戏-1.2.1
title author date CreateTime categories win10 uwp 商业游戏 1.2.1 lindexi 2018-08-10 19:16:50 +0800 2018- ...
- 2018-2-13-C#-解析-sln-文件
title author date CreateTime categories C# 解析 sln 文件 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17:23 ...