`

Java基础之Serializable

    博客分类:
  • Java
 
阅读更多

一、概念

      把Java对象转换为字节序列的过程称为对象的序列化。

 简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。

     

序列化的必要性

 

Java中,一切都是对象,在分布式环境中经常需要将Object从这一端网络或设备传递到另一端。
这就需要有一种可以在两端传输数据的协议。Java序列化机制就是为了解决这个问题而产生。

 

如何序列化一个对象  

实现 java.io.Serializable接口,Serializable内部没有实现任何东西,这个接口是一个制造者(marker)接口。也就是说,对于要实现它的类来说,该接口不需要实现任何方法。它主要用来通知Java虚拟机(JVM),需要将一个对象序列化。

 

二、什么情况下需要序列化

  a)当你想把的内存中的对象保存到一个文件中或者数据库中时候;
  b)当你想用套接字在网络上传送对象的时候;
  c)当你想通过RMI传输对象的时候;

 

三、Java的序列化算法

     a)Make a FileOutputStream

  java 代码
  FileOutputStream fs = new FileOutputStream("foo.ser");

  b)Make a ObjectOutputStream

  java 代码
  ObjectOutputStream os = new ObjectOutputStream(fs);

  c)write the object

  java 代码
  os.writeObject(myObject1);
  os.writeObject(myObject2);
  os.writeObject(myObject3);

  d) close the ObjectOutputStream

  java 代码
  os.close();

 

四、注意事项:

  1:当一个对象被序列化时,只保存对象的非静态成员变量(包括声明为private的变量),不能保存任何的成员方法和静态的成员变量。

  2:如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被序列化。

  3:如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化。

 

 

 

五、举例说明

java 代码

 

  1. import java.io.*;
  2.   
  3. public class  Box implements Serializable  
  4. {  
  5.     private int width;  
  6.     private int height;  
  7.   
  8.     public void setWidth(int width){  
  9.         this.width  = width;  
  10.     }  
  11.     public void setHeight(int height){  
  12.         this.height = height;  
  13.     }  
  14.   
  15.     public static void main(String[] args){  
  16.         Box myBox = new Box();  
  17.         myBox.setWidth(50);  
  18.         myBox.setHeight(30);  
  19.   
  20.         try{  
  21.             FileOutputStream fs = new FileOutputStream("foo.ser");  
  22.             ObjectOutputStream os =  new ObjectOutputStream(fs);  
  23.             os.writeObject(myBox);  
  24.             os.close();  
  25.         }catch(Exception ex){  
  26.             ex.printStackTrace();  
  27.         }  
  28.     }  
  29.       
  30. }  

 

六、 反序列化

    将流转化成对象的过程称之为反序列化。

 反序列化主要依赖java.io.ObjectInputStream类,该类对java.io.InputStream进一步做了封装,这里主要使用ObjectInputStream类的readObject()方法实现序列化功能

Demo:

 

 

/**

     *反序列化,将磁盘文件转化为对象

     */

    publicstatic User readObject(File f) throws Exception{

       InputStream is=new FileInputStream(f);

       //ObjectOutputStream 核心类

       ObjectInputStream ois=new ObjectInputStream(is);

       return (User)ois.readObject();

    }

 

 七、serialVersionUID

  序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致  InvalidClassException。可序列化类可以通过声明名为 "serialVersionUID" 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)显式声明其自己的 serialVersionUID:

 ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;

  如果可序列化类未显式声明 serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认 serialVersionUID 值,如“Java(TM) 对象序列化规范”中所述。不过,强烈建议 所有可序列化类都显式声明 serialVersionUID 值,原因是计算默认的 serialVersionUID 对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的InvalidClassException。因此,为保证 serialVersionUID 值跨不同 java 编译器实现的一致性,序列化类必须声明一个明确的 serialVersionUID 值。还强烈建议使用 private 修饰符显示声明 serialVersionUID(如果可能),原因是这种声明仅应用于直接声明类 -- serialVersionUID 字段作为继承成员没有用处。数组类不能声明一个明确的 serialVersionUID,因此它们总是具有默认的计算值,但是数组类没有匹配 serialVersionUID 值的要求。 

 

分享到:
评论

相关推荐

    Java基础教程完整版

    Java基础教程完整版 Java基础教程完整版是JAVE_LOVER作者提供的一系列Java教程,总共包含18个章节,涵盖了JavaSE基本...Java基础教程完整版涵盖了JavaSE基本知识点、UML建模、单元测试等内容,是Java学习的不二之选。

    java基础面试题,java基础面试题,java基础面试题

    以下是一些常见的Java基础知识面试题及解答: 1. **JVM、JRE、JDK的区别**: - **JVM (Java Virtual Machine)** 是Java的核心,它负责解析并执行字节码,实现跨平台运行。 - **JRE (Java Runtime Environment)** ...

    java 基础知识资料下载

    Java基础知识涵盖了广泛的编程概念和技术,这里我们将聚焦于Java文件操作这一主题,这在日常开发中是非常常见的需求。在Java中,文件操作主要包括创建、删除、判断文件或目录的存在性等。 1. **File类**: - `File...

    Java标准类库(java基础类)

    ### Java标准类库(java基础类) #### 概述 Java标准类库是Java编程语言的核心组成部分之一,提供了丰富的API供开发者使用。本篇文档主要介绍`java.io`包下的核心概念及其应用,包括数据流处理、序列化、以及文件...

    JAVA基础教程 大数据开发

    Java基础教程是学习大数据开发的重要基石,因为它提供了一种强大且灵活的语言平台,为处理大量数据提供了必要的工具和框架。本教程将深入讲解以下几个关键知识点: 1. **Java语言基础**:Java是一种强类型、面向...

    java基础知识 io

    Java基础知识是学习Java编程语言的基石,其中包括对输入/输出(IO)的理解和应用。Java IO是Java平台中处理数据输入和输出的核心组件,对于任何Java开发者来说,掌握这一部分的知识至关重要。以下将详细阐述Java基础...

    java基础思维导图

    Java基础思维导图涵盖了Java SE(标准版)的核心概念,对于初学者来说是理解这门编程语言的关键。Java SE是Java平台的基础,包含了用于开发和运行桌面应用、服务器端应用和网络应用的所有必要组件。本导图将帮助你...

    2024年Java基础面试题,附带详细解析答案

    ### 2024年Java基础面试题及解析 #### 1. 什么是 Java? **答案解析:** Java 是一种广泛使用的高级编程语言,由 Sun Microsystems 在 1995 年开发并发布。它的主要特点包括面向对象、平台独立性、安全性、可移植...

    北京动力节点Java零基础教程006 IO流作业答案,自己写的

    本教程“北京动力节点Java零基础教程006”聚焦于IO流的使用,这是Java中处理输入和输出数据的核心技术。IO流允许程序与外部资源(如文件、网络、内存等)进行数据交换,是Java中不可或缺的一部分。 首先,让我们...

    【java系列文章】java 基础知识

    【Java系列文章】Java 基础知识涵盖了Java开发中的核心概念和常见问题,以下是针对这些知识点的详细解析: ...以上就是Java基础知识的详细解读,涵盖了从基础到进阶的多个方面,有助于深入理解Java编程的核心概念。

    java基础学习内容

    ### Java基础学习内容详解 #### 一、Java基础概述 Java是一种广泛使用的编程语言,具有简单性、面向对象、健壮性、安全性、平台独立性等特点。Java的基础学习内容是学习Java开发的第一步,它包括了Java语言的基本...

    毕向东Java基础总结(超级经典)

    【毕向东Java基础总结】 Java,作为一种广泛应用的高级编程语言,以其“一次编写,到处运行”的跨平台特性,深受开发者喜爱。毕向东老师的Java基础总结,是一部针对Java初学者的经典教程,涵盖了Java语言的核心概念...

    java 基础面试题

    Java基础面试题涵盖了广泛的Java知识领域,包括面向接口编程、集合框架、类加载机制、数据连接池以及JSP内置对象等。以下是这些知识点的详细解释: 1. **可序列化**:在Java中,如果一个对象需要在网络中传输或者...

    Java基础学习30.pdf

    这份"Java基础学习30.pdf"资源提供了全面的学习路径,旨在帮助初学者快速掌握Java基础,并为找工作做好准备。以下是一些重要的Java基础知识点: 1. **转换流**: - 转换流允许我们将字节流转换为字符流,以便处理...

    java的基础测试题(带答案)

    题目中提到了`Serializable`接口,这是Java中用于标识可以序列化的类的接口。实现这个接口的类可以使用`writeObject()`和`readObject()`方法来控制序列化和反序列化的过程。 ### 9. Java IO流 IO流是Java中用于...

    java基础的应用

    ### Java基础的应用知识点详解 #### 一、面向对象基础概览 面向对象编程(OOP)是一种编程范式,它将程序中的数据和处理这些数据的方法组织在一起形成对象。Java作为一种典型的面向对象语言,其核心特性包括封装、...

    Java图书管理系统(IO流版)(csdn)————程序.pdf

    本文总结了Java图书管理系统(IO流版)的主要知识点,涵盖了Java基础语法、流程控制、面向对象思想、封装、继承、多态、接口、异常、集合、IO流等多方面的知识。 一、Java基础语法 * 掌握Java的基本语法,包括变量...

Global site tag (gtag.js) - Google Analytics