java序列化接口Serializable的使用

来自:http://wang09si.blog.163.com/blog/static/170171804201373195046397/

首先要明白,什么是序列化?
我们经常看到一个实体类实现Serializable接口,这种用法就是序列化。目的是保存对象的状态,以便将它读取出来。
序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候再获得。
序列化将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例
Java为我们提供一种比较好的保存对象状态的机制,那就是序列化。
也就是说,保存状态和读取状态的事java已经帮我们做了,我们只需调相应的方法就可以了。

序列化的什么特点:
如果某个类能够被序列化,其子类也可以被序列化。声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态,
transient代表对象的临时数据。

其次要搞清楚,什么情况下需要实例化?
 1、当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
 2、当你想用套接字在网络上传送对象的时候;
 java
对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用
对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。
 3、当你想通过RMI传输对象的时候;
 RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。

最后,就是如何实现序列化的?
 在没有序列化前,每个保存在堆(Heap)中的对象都有相应的状态(state),即实例变量(instance
ariable)比如: 
 Foo  myFoo = new Foo();
 myFoo .setWidth(37);

myFoo.setHeight(70);

当通过下面的代码序列化之后,MyFoo对象中的width和Height实例变量的值(37,70)都被保存到foo.ser文件中,这样以后又可以把它
从文件中读出来,重新在堆中创建原来的对象。当然保存时候不仅仅是保存对象的实例变量的值,JVM还要保存一些小量信息,比如类的类型等以便恢复原来的对象。
 FileOutputStream
fs = new FileOutputStream("foo.ser");
 ObjectOutputStream os = new
ObjectOutputStream(fs);
 os.writeObject(myBox);
 os.close();
 
 ObjectInputStream
in = new ObjectInputStream (new FileInputStream("foo.ser"));
 Box box = (Box)
(in.readObject());
 System.out.println(box.toString());
 System.out.println(box.height);
 in.close();

完整例子:
package wzq.j2se.erializables;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import
java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import
java.io.Serializable;

public class Box implements Serializable {
 private int width;
 private
int height;

public void setWidth(int width) {
  this.width = width;
 }

public void setHeight(int height) {
  this.height = height;
 }

public static void main(String[] args) {
  Box myBox = new
Box();
  myBox.setWidth(50);
  myBox.setHeight(30);
  try
{
   FileOutputStream fs = new
FileOutputStream("foo.ser");
   ObjectOutputStream os = new
ObjectOutputStream(fs);
   os.writeObject(myBox);
   os.close();
   
   ObjectInputStream
in = new ObjectInputStream (new FileInputStream("foo.ser"));
   Box box =
(Box)
(in.readObject());
   System.out.println(box.toString());
   System.out.println(box.height);
   in.close();
  }
catch (Exception ex) {
   ex.printStackTrace();
  }
 }
} //
writeObject和readObject本身就是线程安全的,传输过程中是不允许被并发访问的。所以对象能一个一个接连不断的传过来

子类:

package
wzq.j2se.erializables;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import
java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ExtendsBox extends Box{
 int age;

public int getAge() {
  return age;
 }

public void setAge(int age) {
  this.age = age;
 }
 
 public
static void main(String[] args) {
  ExtendsBox eb = new
ExtendsBox();
  eb.setAge(101);
  try {
   FileOutputStream fs = new
FileOutputStream("abc");
   ObjectOutputStream os = new
ObjectOutputStream(fs);
   os.writeObject(eb);
   os.close();
   
   ObjectInputStream
in = new ObjectInputStream (new FileInputStream("abc"));
   ExtendsBox box =
(ExtendsBox)
(in.readObject());
   System.out.println(box.toString());
   System.out.println(box.getAge());
   in.close();
  }
catch (Exception ex)
{
   ex.printStackTrace();
  }
 }
}

首先要明白,什么是序列化?
我们经常看到一个实体类实现Serializable接口,这种用法就是序列化。目的是保存对象的状态,以便将它读取出来。
序列化就是将一个对象的状态(各个属性量)保存起来,然后在适当的时候再获得。
序列化将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例
Java为我们提供一种比较好的保存对象状态的机制,那就是序列化。
也就是说,保存状态和读取状态的事java已经帮我们做了,我们只需调相应的方法就可以了。

序列化的什么特点:
如果某个类能够被序列化,其子类也可以被序列化。声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态,
transient代表对象的临时数据。

其次要搞清楚,什么情况下需要实例化?
 1、当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
 2、当你想用套接字在网络上传送对象的时候;
 java
对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用
对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。
 3、当你想通过RMI传输对象的时候;
 RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。

最后,就是如何实现序列化的?
 在没有序列化前,每个保存在堆(Heap)中的对象都有相应的状态(state),即实例变量(instance
ariable)比如: 
 Foo  myFoo = new Foo();
 myFoo .setWidth(37);

myFoo.setHeight(70);

当通过下面的代码序列化之后,MyFoo对象中的width和Height实例变量的值(37,70)都被保存到foo.ser文件中,这样以后又可以把它
从文件中读出来,重新在堆中创建原来的对象。当然保存时候不仅仅是保存对象的实例变量的值,JVM还要保存一些小量信息,比如类的类型等以便恢复原来的对象。
 FileOutputStream
fs = new FileOutputStream("foo.ser");
 ObjectOutputStream os = new
ObjectOutputStream(fs);
 os.writeObject(myBox);
 os.close();
 
 ObjectInputStream
in = new ObjectInputStream (new FileInputStream("foo.ser"));
 Box box = (Box)
(in.readObject());
 System.out.println(box.toString());
 System.out.println(box.height);
 in.close();

完整例子:
package wzq.j2se.erializables;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import
java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import
java.io.Serializable;

public class Box implements Serializable {
 private int width;
 private
int height;

public void setWidth(int width) {
  this.width = width;
 }

public void setHeight(int height) {
  this.height = height;
 }

public static void main(String[] args) {
  Box myBox = new
Box();
  myBox.setWidth(50);
  myBox.setHeight(30);
  try
{
   FileOutputStream fs = new
FileOutputStream("foo.ser");
   ObjectOutputStream os = new
ObjectOutputStream(fs);
   os.writeObject(myBox);
   os.close();
   
   ObjectInputStream
in = new ObjectInputStream (new FileInputStream("foo.ser"));
   Box box =
(Box)
(in.readObject());
   System.out.println(box.toString());
   System.out.println(box.height);
   in.close();
  }
catch (Exception ex) {
   ex.printStackTrace();
  }
 }
} //
writeObject和readObject本身就是线程安全的,传输过程中是不允许被并发访问的。所以对象能一个一个接连不断的传过来

子类:

package wzq.j2se.erializables;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import
java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ExtendsBox extends Box{
 int age;

public int getAge() {
  return age;
 }

public void setAge(int age) {
  this.age = age;
 }
 
 public
static void main(String[] args) {
  ExtendsBox eb = new
ExtendsBox();
  eb.setAge(101);
  try {
   FileOutputStream fs = new
FileOutputStream("abc");
   ObjectOutputStream os = new
ObjectOutputStream(fs);
   os.writeObject(eb);
   os.close();
   
   ObjectInputStream
in = new ObjectInputStream (new FileInputStream("abc"));
   ExtendsBox box =
(ExtendsBox)
(in.readObject());
   System.out.println(box.toString());
   System.out.println(box.getAge());
   in.close();
  }
catch (Exception ex) {
   ex.printStackTrace();
  }
 }
}

serialVersionUID作用:
      
序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。
有两种生成方式:
       一个是默认的1L,比如:private
static final long serialVersionUID = 1L;
      
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:
       private static final   long    
serialVersionUID = xxxxL;

当你一个类实现了Serializable接口,如果没有定义serialVersionUID,Eclipse会提供这个提示功能告诉你去定义
。在Eclipse中点击类中warning的图标一下,Eclipse就会自动给定两种生成的方式。如果不想定义它,在Eclipse的设置中也
      
可以把它关掉的,设置如下:
        Window ==> Preferences ==> Java ==> Compiler
==> Error/Warnings ==>
        Potential programming problems

将Serializable class without serialVersionUID的warning改成ignore即可。

如果你没有考虑到兼容性问题时,就把它关掉,不过有这个功能是好的,只要任何类别实现了Serializable这个接口的话,如果没有加入
serialVersionUID,Eclipse都会给你warning提示,这个serialVersionUID为了让该类别
Serializable向后兼容。

如果你的类Serialized存到硬盘上面后,可是后来你却更改了类别的field(增加或减少或改名),当你Deserialize时,就会出现Exception的,这样就会造成不兼容性的问题。

但当serialVersionUID相同时,它就会将不一样的field以type的预设值Deserialize,可避开不兼容性问题。

时间: 2024-10-18 00:55:57

java序列化接口Serializable的使用的相关文章

Java序列化接口Serializable接口的作用总结

转载 http://www.cnblogs.com/DreamDrive/p/4005966.html 一个对象有对应的一些属性,把这个对象保存在硬盘上的过程叫做"持久化". 把堆内存中的对象的生命周期延长,存入硬盘,做持久化操作.当下次再需要这个对象的时候,我们不用new了,直接从硬盘中读取就可以了.(存储到硬盘是一个文件,不需要我们去解析,如果用记事本打开解析会出现乱码,解析要用特定的方式,不用我们管. 我们只需要读取). 把对象存储到硬盘上的一个文件中,这个文件的标准扩展名是(.

面试题:Java中对象序列化接口(Serializable)的意义

Serializable接口是一个里面什么都没有的接口 它的源代码是public interface Serializable{},即什么都没有. 如果一个接口里面什么内容都没有,那么这个接口是一个标识接口,比如,一个学生遇到一个问题,排错排了几天也没解决,此时,她举手了(示意我去帮他解决),然后我过去,帮他解决了,那么这个举手其实就是一个标识,自己不能解决的问题标示我去帮他解决,在Java中的这个Serializable接口是给JVM看的,告诉JVM,我不做这个类的序列化了,你(JVM)给我序

Java序列化,serializable

Java 串行化技术可以使你将一个对象的状态写入一个Byte 流里,并且可以从其它地方把该Byte 流里的数据读出来,重新构造一个相同的对象.这种机制允许你将对象通过网络进行传播,并可以随时把对象持久化到数据库.文件等系统里.Java的串行化机制是RMI.EJB等技术的技术基础.用途:利用对象的串行化实现保存应用程序的当前工作状态,下次再启动的时候将自动地恢复到上次执行的状态. 序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化.可以对流化后的对象进行读写操作,也可将流化后

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

目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 Java 序列化和反序列化(二)Serializable 源码分析 - 1 在上一篇文章中讲解了一下 Serializable 的大致用法,本节重点关注 Java 序列化的实现,围绕 ObjectOutputStream#writeObject 方法展开. 1. Java 序列化接口 Java 为了方便开发人员将 Java 对象进行序列化及反序列化提供了一套方便的 API 来支持.其中包

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

Java序列化的几种方式以及序列化的作用 本文着重讲解一下Java序列化的相关内容. 如果对Java序列化感兴趣的同学可以研究一下. 一.Java序列化的作用    有的时候我们想要把一个Java对象变成字节流的形式传出去,有的时候我们想要从一个字节流中恢复一个Java对象.例如,有的时候我们想要 把一个Java对象写入到硬盘或者传输到网路上面的其它计算机,这时我们就需要自己去通过java把相应的对象写成转换成字节流.对于这种通用 的操作,我们为什么不使用统一的格式呢?没错,这里就出现了java

【Java基础第一弹】Java序列化基础篇

Java类通过实现java.io.Serializable 接口便可启用其序列化功能.实现了序列化的类的实例可以在不同的系统或JVM间传递,并且不会丢失原实例的相关状态及值. 为一个类开启序列化功能只需实现Serializable 接口即可,仅仅作为使用者可以不必了解其内部的更深层次的实现及流程,但是如果想要更好的使用序列化功能就需要与我一起详细的学习和了解它. 1.什么是Java序列化 Java类通过实现java.io.Serializable 接口以启用其序列化功能: import java

Java序列化的几种方式

本文着重解说一下Java序列化的相关内容. 假设对Java序列化感兴趣的同学能够研究一下. 一.Java序列化的作用    有的时候我们想要把一个Java对象变成字节流的形式传出去,有的时候我们想要从一个字节流中恢复一个Java对象.比如.有的时候我们想要 把一个Java对象写入到硬盘或者传输到网路上面的其他计算机,这时我们就须要自己去通过java把对应的对象写成转换成字节流.对于这样的通用 的操作.我们为什么不使用统一的格式呢?没错,这里就出现了java的序列化的概念.在Java的Output

Java序列化Serializable和Externalizable

纸上得来终觉浅,绝知此事要躬行  --陆游       问渠那得清如许,为有源头活水来  --朱熹 什么是Java序列化?为什么出现Java序列化?如何实现Java序列化? 一.什么是Java序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 二.为什么出现Java序列化 两个进程之间进行通信时,须要传输各种信息.比方文本,图像,声音等等,这些信息是通过二进制流的形式进行传输的. 那么进程之间是不是也能够传递对象数据呢?答案是

Java序列化与反序列化学习(二):序列化接口说明

一.序列化类实现Serializable接口 Serializable接口没有方法,更像是个标记.有了这个标记的Class就能被序列化机制处理. ObjectOutputStream只能对Serializable接口的类的对象进行序列化.默认情况下,ObjectOutputStream按照默认方式序列化,这种序列化方式仅仅对对象的非transient的实例变量进行序列化,而不会序列化对象的transient的实例变量,也不会序列化静态变量. 当ObjectOutputStream按照默认方式反序