上一篇我们简单的了解了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序列化(二)的更多相关文章

  1. Java 序列化和反序列化(二)Serializable 源码分析 - 1

    目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 2. ObjectOutputStream 源码分析 2.1 ObjectOutputSt ...

  2. 理解Java对象序列化(二)

    关于Java序列化的文章早已是汗牛充栋了,本文是对我个人过往学习,理解及应用Java序列化的一个总结.此文内容涉及Java序列化的基本原理,以及多种方法对序列化形式进行定制.在撰写本文时,既参考了Th ...

  3. Java序列化与反序列化

    Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?本文围绕这些问题进行了探讨. 1.Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列 ...

  4. [转] Java序列化与反序列化

    原文地址:http://blog.csdn.net/wangloveall/article/details/7992448 Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java ...

  5. Java序列化的几种方式以及序列化的作用

    Java序列化的几种方式以及序列化的作用 本文着重讲解一下Java序列化的相关内容. 如果对Java序列化感兴趣的同学可以研究一下. 一.Java序列化的作用    有的时候我们想要把一个Java对象 ...

  6. Java学习笔记(十七)——java序列化

    [前面的话] 做项目总是要用到很多东西,遇到一个新的知识,并不是这个知识出来的时间短,而是对于自己来说是新的,所以就需要自己去学习,希望今后可以提高学习的效率. 这篇文章是关于Java 序列化的,选择 ...

  7. java基础知识回顾之javaIO类--java序列化和反序列化

    /** *  * 一:理解序列化反序列化及其应用 * 序列化:把堆内存的对象转化成字节流的过程. * 反序列化:把字节流序列恢复重构成对象的过程. * 对象的序列化的用途:1.把对象的字节序列持久化, ...

  8. Java序列化接口的作用总结

    一个对象有对应的一些属性,把这个对象保存在硬盘上的过程叫做”持久化”. 把堆内存中的对象的生命周期延长,存入硬盘,做持久化操作.当下次再需要这个对象的时候,我们不用new了,直接从硬盘中读取就可以了. ...

  9. Java序列化技术

    Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化? Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象 ...

  10. java 序列化 serialVersionUID 的作用 和 两种添加方式

    serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...

随机推荐

  1. vue-router在新窗口打开页面

    1. <router-link>标签实现新窗口打开: <router-link target="_blank" :to="{path:'/app/dat ...

  2. Flex AIR应用GPS定位功能(Android和IOS)

    说明: 使用AIR进行GPS定位功能实现时,会经常判断GPS是否打开.一般的官方或者书上的介绍的方法,测试后,只能对Android系统进行判断,而对ios系统则无法进行判断. 经过研究测试,终于解决实 ...

  3. 2018-8-10-git-提交添加-emoij-文字

    title author date CreateTime categories git 提交添加 emoij 文字 lindexi 2018-08-10 19:16:52 +0800 2018-2-1 ...

  4. Python3 dir() 函数

    Python dir() 函数 描述 dir() 函数不带参数时,返回当前范围内的变量.方法和定义的类型列表:带参数时,返回参数的属性.方法列表.如果参数包含方法__dir__(),该方法将被调用.如 ...

  5. H5 操作class 类样式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. git把某个文件去除版本控制

    谢谢@jessicway 同学的提醒.我之前没考虑只需要删除服务器上已提交的文件,但是本地不想删除的情况. 我们先看看 git rm 命令的说明 可以看到其实加上 --cached 参数就可以实现只去 ...

  7. UPC个人训练赛第十五场(AtCoder Grand Contest 031)

    传送门: [1]:AtCoder [2]:UPC比赛场 [3]:UPC补题场 参考资料 [1]:https://www.cnblogs.com/QLU-ACM/p/11191644.html B.Re ...

  8. 【js】React-Native 初始化时报错

    一.按照官网的步骤一步一步的操作,到最后  react-native init AwesomeProject  时就是报错 报错信息如下图 然后我下载了这个模块  npm install prompt ...

  9. zookeeper(1)-概述

    ZooKeeper概述 ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现.它提供了简单原始的功能,分布式应用可以基于它实现更高级 ...

  10. 【43.49%】【hdu3308】LCIS

    Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission ...