Java对象序列化原理以及Serializable接口_Andyzty的博客-程序员秘密

技术标签: Java开发笔记  二进制数据传输  java基础及多线程  ObjectOutputStream  serializable  java序列化  ObjectInputStream  

Java对象的序列化就是把一个对象变成二进制的数据流的一中方法,通过对象的序列化可以方便的实现对象的传输和存储。

原理是:对象------------->转换----------------->将对象转变为二进制的数据

            在对象序列化时,只有其属性被序列化(每个对象都具备相同的方法,但是每个对象的属性不一定相同,也就是说对象保存的只有其属性信息)

那么一个类的对象要被序列化,这该类就必须实现java.io.Serializable接口,其源码如下:

public interface Serializable {
}

    可以发现此接口没有定义任何的方法,此接口只是一个标识接口,表示一个类具备了别序列化的能力。

    如果要完成对象的输入或输出,必须依赖对象的输入流(ObjectInputStream)和 对象输出流(ObjectOutputStream)。

   1、使用对象输出流输出序列化对象的过程称之为序列化。

   2、使用对象输入流读入对象的过程称之为反序列话。

   程序-------------->ObjectOutputStream------------------->序列化对象<----------------------ObjectInputStream-----------------------------程序

                                         序列化                                                                                                         反序列化

  

   一、ObjectOutputStream对象输出流

      他是OutputStream字节数出流的子类,主要有如下方法:

       1、 public  ObjectOutputStream(OutputStream out) throw IOException  构造方法  如传入输出流对象

       2、 public final void writeObject(Object obj) throw IOException   输出对象

其实现如下:

定义一个序列化类。

package andy.serializable.test;

import java.io.Serializable;

/**
 * @author Zhang,Tianyou version:2014-11-20 下午2:41:12
 * 
 * 
 */

public class Student implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6095384564471868081L;

	// 实现serializable是指成为序列化类

	private String name;

	private int age;

	public Student() {
	}

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

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}

将对象输出到文件d:tes.txt 文件中:

package andy.serializable.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

/**  
 * @author Zhang,Tianyou  
 * version:2014-11-20 下午2:45:24  
 * 
 *  
 */

public class ObjectOutputStreamTest {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		File file = new File("d:" + File.separator + "test.txt");
		
		ObjectOutputStream oos = null;
		
		OutputStream outputStream = new FileOutputStream(file);
		
		oos = new ObjectOutputStream(outputStream);
		
		oos.writeObject(new Student("小明", 23));
		
		outputStream.close();
		
		oos.close();
	}

}

其二进制数据结果如下如下:



  二、ObjectInputStream对象输入流

          能够将被序列化的对象反序列话。是InputStream的子类,实例化是必须接受一个InputStream输入流对象。

   其主要方法如下:

          1、public ObjectInputStream(InputStream in) throw IOException  构造方法

          2、public final Object readObject() throw IOException, ClassNotFoundException 读取指定位置的对象

其实现如下:

package andy.serializable.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;

/**
 * @author Zhang,Tianyou version:2014-11-20 下午2:45:46
 * 
 * 
 */

public class ObjectInputStreamTest {

	/**
	 * @param args
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public static void main(String[] args) throws IOException,
			ClassNotFoundException {
		// TODO Auto-generated method stub
		File file = new File("d:" + File.separator + "test.txt");

		ObjectInputStream ois = null;

		InputStream inputStream = new FileInputStream(file);

		ois = new ObjectInputStream(inputStream);

		Object obj = ois.readObject();
		Student student = (Student) obj;

		ois.close();

		inputStream.close();

		System.out.println("test内容: name:" + student.getName() + "age:"
				+ student.getAge());

	}

}

运行如下:

test内容: name小明age:23


  三、也可以自定义序列化接口,可以指定自己希望序列化的内容,只需实现Externalizable接口。


 四、Serializable接口实现的操作实际是将一个对象的全部属性进行了序列化,当然也可以通过Externalizable接口实现部分属性的序列化,但更简便的方法是使用transient关键字声明不需要序列化的接口。

例如:

   private transient String name;

那么name是不会被序列化的。


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/fengshizty/article/details/41309693

智能推荐

QT creator 初次使用C++的nullptr出现 use of undeclared identifier 'nullptr' 的问题_Fuxuancode的博客-程序员秘密

搜寻了很多回答发现,这种情况需要加个编译时的flag解决方法是打开 .pro 文件并在里面添加QMAKE_CXXFLAGS += -std=c++0x问题基本能解决

html点击按钮状态改变,html点击按钮改变文字怎么实现_Mike昊的博客-程序员秘密

html点击按钮改变文字的实现方法:1.创建一个html文件;2.在html文件中添加html代码架构;3.在body标签里面使用p标签和button标签实现一个按钮和一段文本;4.在html标签里面添加script标签并设置点击按钮改变文本的功能;5.通过浏览器方式查看设计效果。html点击按钮改变文字的实现方法:1.首先创建一个html文件。2.在html文件中添加html代码架构。html&...

《推箱子》python小游戏(第一期)_剑心211的博客-程序员秘密

欢迎加入我们卧虎藏龙的python讨论qq群:729683466●导 语●以前,公众号推送小游戏代码的时候从没有仔细讲过代码的原理主要是代码细节太多了一期根本讲不完这一次我们准备分很多...

【干货】李航老师《统计学习方法》(第2版)清华PPT课件分享_zenRRan的博客-程序员秘密

点击上方,选择星标或置顶,每天给你送干货!阅读大概需要7分钟跟随小博主,每天进步一丢丢参考:AI派李航博士的《统计学习方法》可以说是机器学习的入门宝典。现如今,统计学习方法(第2版)于今...

设计模式之创建型_lxz 设计_lxz_lj的博客-程序员秘密

早期的软件开发,基本都是面向过程开发。它逻辑顺畅,易于理解。基本上是顺着CPU运行的前后逻辑来展开的,有利于理解计算机的运行过程。随着软件规模的扩大,人们认识到业务的复杂度开始超过计算机本身的复杂度,于是开始转向了面向对象开发。面向对象,本质是代码逻辑对真实世界对象的模拟,从而使程序员对业务逻辑的理解变的容易。代价是需要隐藏了代码在计算机中的运行逻辑,这就是C和C++的主要区别,即在编

I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this Tensor..._weixin_34107739的博客-程序员秘密

问题:安装TensorFlow(CPU版本),使用pip install tensorflow安装,安装一切顺利,但是在跑一个简单的程序时,遇到如下情况: 大概意思是:你的CPU支持AVX扩展,但是你安装的TensorFlow版本无法编译使用。原因:除了通常的算术和逻辑,现代CPU提供了许多低级指令,称为扩展,例如, SSE2,SSE4,AVX等来自维基百科:高级矢量扩展(AVX...

随便推点

Java学习笔记(语言基础及面向对象)_阿腾木的博客-程序员秘密

文章目录第 1 章 Java语言概述与开发环境第 3 章 数据类型和运算符第 5 章 面向对象(上)第 1 章 Java语言概述与开发环境Java虚拟机(JVM : Java Virtual Machine)java语言里负责解释执行字节码文件,是运行Java字节码文件的虚拟计算机。当使用Java编译器编译Java程序时,生成的是与平台无关的字节码,这些字节码不面向任何具体平台,只面向J...

静态库的创建和使用(Win10+VS2022_静态库的创建与使用_Alexabc3000的博客-程序员秘密

静态库的创建使用VS2022新建空项目,项目名为MyStaticLib,项目所在文件夹为“E:\temp”。点击创建,即完成项目的创建。在VS2022的“解决方案资源管理器”视图中,添加名为“MyStaticLib.h”(文件名可以任意)的头文件(右键单击“头文件-添加-新建项-头文件”),输入如下代码:#ifndef _MY_STATIC_LIB_H_#define _MY_STATIC_LIB_H_int my_static_add(int a, in..

为什么大家都在Instagram上引流其他服务_instagram群控软件_Twitter群推王的博客-程序员秘密

商业世界总是一个竞争激烈的空间,作为企业主,您必须继续考虑将新业务推向市场的新方法,没有比使用社交媒体更好的方法了。现在,我知道你在想什么:为什么在我的营销策略运作良好时重新发明轮子?虽然您目前的营销策略现在很有效,但您需要在竞争中保持领先,以便在未来保持成功。而且,说实话,如果你不去顾客所在的地方,你不能指望仍然保持领先地位。事实是社交媒体,特别是Instagram已经风靡商业世界。每天有大约5亿活跃用户,你会同意Instagram是最好的社交网络之一。因此,您在广告上取得成功的最佳选择是在I

Oracle排序分析函数_weixin_33968104的博客-程序员秘密

在Oracle自拓展SQL功能中,分析函数(Analytical Function)是非常强大的工具。本篇我们介绍几个Oracle典型的排序分析函数,来帮助我们解决实际问题。1、从rownum谈起选择Oracle 11gR2进行测试基础表EMP,并对字段 sal 排序常见的功能需求,是先用order by排序,之后用rownum从1开始标记。但是,ro...

Python OpenCV:利用鼠标移动缩放图片_北冥有鱼wyh的博客-程序员秘密

在OpenCV中使用鼠标移动缩放图片实现目标  在OpenCV中通过鼠标左键拖拽移动图片,通过鼠标滚轮前后旋转放大缩小图片。实现背景  在前一篇博客&amp;amp;amp;quot;在OpenCV中使用滚动条显示大图&amp;amp;amp;quot;中发现自己画滚动条移动大图略显繁琐,且缩放图片存在一定不足,故尝试利用鼠标拖拽来实现图片移动,同时完善使用鼠标滚轮缩放图片的程序。实现方法  利用OpenCV中的鼠标事件实现。当鼠标左键点击时保存初始坐...

App 如何快速重启(编译)_swift 重启app_~废弃回忆 �༄的博客-程序员秘密

iOS 原生代码的编译调试,都是通过一遍又一遍地编译重启 App 来进行的。所以,项目代码量越大,编译时间就越长。虽然我们可以通过将部分代码先编译成二进制集成到工程里,来避免每次都全量编译来加快编译速度,但即使这样,每次编译都还是需要重启 App,需要再走一遍调试流程。对于开发者来说,提高编译调试的速度就是提高生产效率。试想一下,如果上线前一天突然发现了一个严重的 bug,每次编译调试都要耗费几十分钟,结果这一天的黄金时间,一晃就过去了。到最后,可能就是上线时间被延误。这个责任可不轻啊。那么问题来了

推荐文章

热门文章

相关标签