java中序列化与反序列化的冷知识

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992

关于什么是序列化,和为什么要序列化的知识就不再阐述了,本文主要探讨一些特殊点的情况。

1.java中如何实现序列化和反序列化

下面的代码是进行序列化的简单实例

public static void main(String[] args) {

		System.out.println("-----------------序列化----------------------↓");

		Student student1 = new Student(10, "zhao");
		Student student2 = new Student(15, "kai");
		Student student3 = new Student(20, "qiang");

		ObjectOutputStream objectWriter = null;

		try {

			objectWriter = new ObjectOutputStream(new FileOutputStream(
					new File("./Serializable")));

			objectWriter.writeObject(student1);
			objectWriter.writeObject(student2);
			objectWriter.writeObject(student3);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {

			try {
				objectWriter.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

		System.out.println("-----------------反序列化----------------------↓");
		ObjectInputStream objectInputStream = null;
		try {
			objectInputStream = new ObjectInputStream(new FileInputStream(
					new File("./Serializable")));

			Student s1 = (Student) objectInputStream.readObject();
			Student s2 = (Student) objectInputStream.readObject();
			Student s3 = (Student) objectInputStream.readObject();

			System.out.println(s1.toString());
			System.out.println(s2.toString());
			System.out.println(s3.toString());

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				objectInputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

2.在反序列化的时候,需要调用本类的构造函数吗?

我的测试序列化的类如下,在无参和有参的构造函数中,打印了语句,然后,我们使用上面的序列化和反序列化代码进行测试。

public class Student implements Serializable {

	private int age;
	private String name;

	public Student() {
		System.out.println("Student()");
	}

	public Student(int age, String name) {
		this.age = age;
		this.name = name;
		System.out.println("Student(int age, String name)");
	}

	@Override
	public String toString() {
		return "Student [age=" + age + ", name=" + name + "]";
	}

}

下面是测试结果

-----------------序列化----------------------↓
Student(int age, String name)
Student(int age, String name)
Student(int age, String name)
-----------------反序列化----------------------↓
Student [age=10, name=zhao]
Student [age=15, name=kai]
Student [age=20, name=qiang]

因此,我们可以认为,在反序列化的时候,是不需要调用本类的构造函数的。

2.反序列化的时候,会调用父类的构造函数吗?

我们新创建一个Person类,然后用Student继承自Person,Student的代码如下

public class Student extends Person implements Serializable {

	private int age;
	private String name;

	public Student() {
		System.out.println("Student()");
	}

	public Student(int age, String name) {
		this.age = age;
		this.name = name;
		System.out.println("Student(int age, String name)");
	}

	@Override
	public String toString() {
		return "Student [age=" + age + ", name=" + name + "]";
	}

}

Person类的代码如下

public class Person {

	private boolean sex;

	public Person() {
		System.out.println("Person()");
	}

	public Person(boolean sex) {
		this.sex = sex;
		System.out.println("Person(boolean sex)");
	}

	@Override
	public String toString() {
		return "Person [sex=" + sex + "]";
	}

}

同样,我把Person的构造函数都进行了输出,然后利用上面的代码进行测试,下面是测试结果

-----------------序列化----------------------↓
Person()
Student(int age, String name)
Person()
Student(int age, String name)
Person()
Student(int age, String name)
-----------------反序列化----------------------↓
Person()
Person()
Person()
Student [age=10, name=zhao]
Student [age=15, name=kai]
Student [age=20, name=qiang]

我们可以看到,虽然Student的构造函数没有调用,但是Person的无参构造函数却调用了,这也就是说,在反序列化的时候,本类的构造函数不会调用,但是会调用其父类的无参构造函数。在没有继承的情况下,会调用所有类的父类,即Object的构造函数。

3.当需要序列化的类的父类没有实现序列化的时候,能否将父类中protect的属性进行序列化和反序列化呢?

为了进行测试,我们需要将Person类的代码进行修改,下面修改之后的代码

public class Person {

	protected boolean sex;

	public Person() {
		System.out.println("Person()");
	}

	public Person(boolean sex) {
		this.sex = sex;
		System.out.println("Person(boolean sex)");
	}

	@Override
	public String toString() {
		return "Person [sex=" + sex + "]";
	}

}

同时,我们还需要修改Student的toString(),下面是修改之后Student代码

public class Student extends Person implements Serializable {

	private int age;
	private String name;

	public Student() {
		System.out.println("Student()");
	}

	public Student(int age, String name) {
		this.age = age;
		this.name = name;
		System.out.println("Student(int age, String name)");
	}

	public Student(int age, String name, boolean sex) {
		super(sex);
		this.age = age;
		this.name = name;
	}

	@Override
	public String toString() {
		return "Student [age=" + age + ", name=" + name + ", sex=" + sex + "]";
	}

}

我们进行序列化和反序列化,下面是测试结果

-----------------序列化----------------------↓
Person(boolean sex)
Person(boolean sex)
Person()
Student(int age, String name)
-----------------反序列化----------------------↓
Person()
Person()
Person()
Student [age=10, name=zhao, sex=false]
Student [age=15, name=kai, sex=false]
Student [age=20, name=qiang, sex=false]

从结果中可以看到,虽然父类没有进行序列化,但是sex属性也参与了序列化和反序列化操作,因此不影响。

从上面几个测试的结果中,我们可以得出结论:进行序列化和反序列化必须调用其父类的无参的构造函数。

时间: 2024-08-01 10:46:39

java中序列化与反序列化的冷知识的相关文章

Java 中序列化与反序列化引发的思考?

java 中序列化指从对象转变为 二进制流的过程中需要进行序列化,而反序列化指二进制流转换为java 对象.那么有的时候java 存储到数据库不需要序列化, 而计算机系统本质存储的就是二进制文件,数据库的本质又是什么呢? 一.从硬件说起 核心五部分:运算器.控制器.存储器.输入设备.输出设备 根据冯诺伊曼计算机原理,计算机除了五部分外,存储用于存放指令与数据,运算器完成算数与逻辑运算,外部人员通过输入/输出设备操作计算机,且计算机内部是使用二进制表示指令与数据. 其中指定由操作码和地址吗构成,操

Java的序列化与反序列化

Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?本文围绕这些问题进行了探讨. 1.Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 2.为什么需要序列化与反序列化 我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本.图片.音频.视频等, 而这些数据都会以二进制序列的形式在网络上传送.那么当两个Java进程进行通信时,能否实现进程间的对象传送

Java对象序列化和反序列化

Java对象序列化和反序列化 在Java中,我们如果要保存一个对象的瞬时状态值,以便在下次使用时能够得到这些值,或者持久化对象,或者使用RMI(远程方法调用),或在网络中传递对象时,此时我们就需要将对象序列化,实现序列化,我们只要实现Serializable接口,该接口是一个标记接口(Tag interface),即里面没有方法,其主要作用就是告诉JVM该类的对象可以进行序列化. 一般来说,很多类的对象都实现了Serializable接口,但是,有些对象是不能进行序列化的,比如与数据库相关的连接

java 对象序列化与反序列化

Java序列化与反序列化是什么? 为什么需要序列化与反序列化? 如何实现Java序列化与反序列化? 本文围绕这些问题进行了探讨. 1.Java序列化与反序列化  Java序列化是指把Java对象转换为字节序列的过程: Java反序列化是指把字节序列恢复为Java对象的过程. 2.为什么需要序列化与反序列化 我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本.图片.音频.视频等, 而这些数据都会以二进制序列的形式在网络上传送.那么当两个Java进程进行通信时,能否实现进程间的

Java对象序列化与反序列化

Java对象序列化与反序列化 对象序列化的目标是将对象保存在磁盘中或者在网络中进行传输.实现的机制是允许将对象转为与平台无关的二进制流. java中对象的序列化机制是将允许对象转为字节序列.这些字节序列可以使Java对象脱离程序存在,从而可以保存在磁盘上,也可以在网络间传输. 对象的序列化是将一个Java对象写入IO流:与此对应的,反序列化则是从IO流中恢复一个Java对象. 实现序列化 如果要将一个java对象序列化,那么对象的类需要是可序列化的.要让类可序列化,那么这个类需要实现如下两个接口

php中序列化与反序列化在utf8和gbk编码中测试

在php中如果我们统一编码是没有什么问题了,但是很多朋友会发现一个问题就是utf8和gbk编码中返回的值会有所区别: php 在utf8和gbk编码下使用serialize和unserialize互相序列化和反序列化会出现无法成功反序列化的问题. 问题出现的原因主要是在不同编码下strlen函数计算中文字符串长度不同的原因. <?php $array=array('title'=>'php教程分享网','url'=>'http://www.111cn.net'); echo serial

java 打印流 递归复制子文件子文件夹 不同编码文件复制到同一文件中 序列化流反序列化流

package com.swift.jinjie; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.PrintStream; /*从键盘输入一个文件夹路径,利用打印流将该文件夹下的所有文件(包括子文件夹)复制到D盘下temp文件夹下.*/ public class PrintAllT

java开发中序列化与反序列化起到的作用

基本概念: 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储和传输数据. 特别在网络传输中,它的作用显得尤为重要.我们可以把一个类实现序列化,然后在另一端通过反序列化可以得到该对象 例如:我们可以序列化一个对象,不过这个对象要实现序列化方法,并生成序列化号. 这是对一个对象进行序列化和反序列化的过程: public static byte[] serializeObj(Object object){ if (obje

深入分析Java的序列化与反序列化

阅读目录 Java对象的序列化如何对Java对象进行序列化与反序列化序列化及反序列化相关知识ArrayList的序列化ObjectOutputStream总结 序列化是一种对象持久化的手段.普遍应用在网络传输.RMI等场景中.本文通过分析ArrayList的序列化来介绍Java序列化的相关内容.主要涉及到以下几个问题: 怎么实现Java的序列化 为什么实现了java.io.Serializable接口才能被序列化 transient的作用是什么 怎么自定义序列化策略 自定义的序列化策略是如何被调