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会把传来的字节流中的 ...
随机推荐
- HTML5--语法
一.标记方法 1.内容类型(ContentType)还是.text/html 2.声明:<!DOCTYPE html SYSTEM “about:legacy-compat”> 3.字符编 ...
- torch.optim优化算法理解之optim.Adam()
torch.optim是一个实现了多种优化算法的包,大多数通用的方法都已支持,提供了丰富的接口调用,未来更多精炼的优化算法也将整合进来. 为了使用torch.optim,需先构造一个优化器对象Opti ...
- Python--day26--复习
- 洛谷P2719 搞笑世界杯 题解 概率DP入门
作者:zifeiy 标签:概率DP 题目链接:https://www.luogu.org/problem/P2719 我们设 f[n][m] 用于表示还剩下n张A类票m张B类票时最后两张票相同的概率, ...
- python 字符串方法isdigit()
python isdigit() 方法检测字符串是否只有数字组成. 语法: isdigit()方法语法: str.isdigit() 参数:无 返回值: 如果字符串中只含有数字则返回True,否则返回 ...
- codeforce 378 div 2 F —— Drivers Dissatisfaction (最小生成树,LCA,倍增)
官方题解: If you choose any n - 1 roads then price of reducing overall dissatisfaction is equal to min(c ...
- C# 序列类为 xml 可以使用的特性大全
本文告诉大家如何使用序列类,以及序列时可以用到的特性,特性的作用和一些容易被问的问题 最近我在把项目文件修改为 VisualStudio 2017 的格式,请看从以前的项目格式迁移到 VS2017 新 ...
- python模块之hashlib模块
hashlib模块:提供摘要算法 格式: hashlib格式: obj = hashlib.算法(md5,sha....) obj.update(摘要内容:bytes类型) result = obj. ...
- 2018-6-15-win10-uwp-xaml-绑定接口
title author date CreateTime categories win10 uwp xaml 绑定接口 lindexi 2018-6-15 21:7:19 +0800 2018-2-1 ...
- iview+vue查询分页实现
本文为实战坑记录 子组件(共用的搜索组件) <template> <div> <h2>{{pdbTitle}}</h2> <Form ref=&q ...