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会把传来的字节流中的 ...
随机推荐
- H3C TCP与UDP的对比
- Laravel 上传excel,读取并写入数据库 (实现自动建表、存记录值
<?php namespace App\Http\Controllers; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminat ...
- Java Annotation详解(二): 反射和Annotation
前面一篇文<Java Annotation详解(一): 理解和使用Annotation>中,我们或许会觉得,Annotation注释其实并没有多大的作用,除了几个内建的Annotation ...
- Python--day69--ORM外键的正向查询和反向查询
什么是正向查询,什么是方向查询?
- CentOS7增加或修改SSH端口号
https://blog.csdn.net/ausboyue/article/details/53691953 前言:开启某服务或软件的端口,要从该服务或软件监听的端口(多以修改配置文件为主),SeL ...
- mysql 第一课 win7艰难的配置与删除注册表重新安装
mysql 这个安装一定要慎重!慎重!慎重! 重要的事情说三遍.. 不会的一定要按步骤来~出错了真的很难受. 详细教程 --> https://jingyan.baidu.com/album/ ...
- 高可用之keepalived的配置文件详解
! Configuration File for keepalived global_defs { notification_email { acassen@firewall.loc failover ...
- 【hdu 1112】The Proper Key
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...
- 2018-8-10-win10-uwp-x_Bind-无法获得资源
title author date CreateTime categories win10 uwp x:Bind 无法获得资源 lindexi 2018-08-10 19:17:19 +0800 20 ...
- 第3本:Visual Studio程序员箴言
第3本:Visual Studio程序员箴言 Visual Studio 2010是我经常使用的程序开发工具,也知道VS中有大量的快捷键可以帮助提高效率,可惜就是不愿意记忆,最近在学vim的时候快速把 ...