`
ttkktt
  • 浏览: 27838 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

深入了解java序列化之化不肯能为可能

阅读更多

昨天看到我的上一篇博文:深入谈谈java的深拷贝与浅拷贝(http://ttkktt.iteye.com/blog/391171)中的一个评论引发了今日我写这篇博文。

 

首先我们简单说下序列化/反序列化的一些基本概念,

  Java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。

 

  Java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。、

 

  对象序列化包括如下步骤:

 

  1.创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;

 

  2.通过对象输出流的writeObject()方法写对象。

 

  对象反序列化的步骤如下:

 

  1.创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;

 

  2.通过对象输入流的readObject()方法读取对象

 

 

只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式 ,但是仍可手工控制声明为static或transient的数据成员。序列化时,类的所有数据成员应可序列化除了声明为transient 或static的成员。将变量声明为transient告诉JVM我们会负责将变元序列化。将数据成员声明为transient后,序列化过程就无法将其加进对象字节流中,没有从transient数据成员发送的数据。后面数据反序列化时,要重建数据成员(因为它是类定义的一部分),但不包含任何数据,因为这个数据成员不向流中写入任何数据。记住,对象流不序列化static或transient标记的成员。这样我们可以利用这点通过重写writeObject()/readObject()方法来做一些特别的性能优化操作和解决一些特别问题。

 

例如有些时候我们的应用开发完后发现某个程序写的一些对象在做远程调用时不能被序列化,原因是对象的某个成员不能被序列化。这时候要重新改动这个对象已经不太可能。这时候我们就可以重写writeObject()/readObject()来让这个不可序列化的成员能够被远程复制。

 

java.util.ArrayList的源码就是一个很好的例子:

public class ArrayList extends AbstractList implements List, Cloneable, java.io.
Serializable {
private transient Object elementData[];
private int size;
...

private synchronized void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
    // Write out element count, and any hidden stuff
    s.defaultWriteObject();
   // Write out array length
    s.writeInt(elementData.length);
    // Write out all elements in the proper order.
    for (int i=0; i<size; i++)
            s.writeObject(elementData[i]);
    }

    private synchronized void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
    // Read in size, and any hidden stuff
    s.defaultReadObject();
    // Read in array length and allocate array
    int arrayLength = s.readInt();
    elementData = new Object[arrayLength];
    // Read in all elements in the proper order.
    for (int i=0; i<size; i++)
            elementData[i] = s.readObject();
    }
 

 

 

因为elementData数组中存储的“元素”其实仅是对这些元素的一个引用,并不是真正的对象,序列化一个对象的引用是毫无意义的,因为序列化是为了反序列化,当你反序列化时,这些对象的引用已经不可能指向原来的对象了。所以在这儿需要手工的对ArrayList的元素进行序列化操作。这就是writeObject()的作用。对应的readObject()也按照writeObject()方法的顺序从输入流中读取。

 

如果一个类要完全负责自己的序列化,则实现Externalizable接口而不是Serializable接口。Externalizable接口定义包括两个方法writeExternal()与readExternal()。利用这些方法可以控制对象数据成员如何写入字节流.类实现 Externalizable时,头写入对象流中,然后类完全负责序列化和恢复数据成员,除了头以外,根本没有自动序列化。这里要注意了。声明类实现 Externalizable接口会有重大的安全风险。writeExternal()与readExternal()方法声明为public,恶意类可以用这些方法读取和写入对象数据。如果对象包含敏感信息,则要格外小心。这包括使用安全套接或加密整个字节流。


 

0
0
分享到:
评论

相关推荐

    通过实例深入了解java序列化

    通过实例深入了解 Java 序列化,可以帮助开发人员更好地理解 Java 序列化机制,避免一些常见的问题,提高开发效率。本文通过分析一些真实情境,帮助读者轻松牢记 Java 序列化中的一些高级认识。

    Java序列化

    Java序列化是Java平台中的一种标准机制,允许将对象的状态转换为...通过以上知识点的学习,你可以对Java序列化有深入的理解,无论是理论还是实践,都能为你在开发过程中处理对象持久化、数据传输等问题提供有力支持。

    java 序列化时排除指定属性

    Java序列化是Java平台提供的一种持久化机制,它允许我们将一个Java对象转换为字节流,以便存储到磁盘上,或者通过网络进行传输。这使得我们可以保存和恢复对象的状态。实现序列化的类需要实现`Serializable`接口,...

    Java对象序列化标准最新版

    ### Java对象序列化标准知识点详解 #### 一、系统架构概览 **1.1 概览** Java 对象序列化是一种将Java对象的...以上内容涵盖了Java序列化标准的关键知识点,深入了解这些概念有助于更好地理解和应用Java序列化技术。

    C#和Java的序列化反序列化

    本篇文章将深入探讨C#和Java中的序列化与反序列化机制。 首先,我们要了解什么是序列化。序列化是指将对象的状态转化为可存储或可传输的数据格式的过程。这个过程通常将内存中的对象转换成字节流,以便保存到磁盘、...

    java序列化原理与算法

    Java序列化的核心是将对象转换为字节流,这涉及到一系列复杂的操作步骤。 ##### 序列化算法示例 为了更好地理解序列化的过程,我们可以通过一个简单的例子来进行说明。 ```java import java.io.Serializable; ...

    java自动序列化

    Java序列化是将对象转换为字节流的过程,目的是为了保存对象的状态以便稍后恢复或传输到其他地方。通过实现`Serializable`接口,一个Java对象就可以被序列化。这个接口是一个标记接口,没有定义任何方法,仅表示对象...

    Java_序列化的高级认识

    ### Java序列化的高级认识 Java序列化作为Java技术体系中的一个重要组成部分,其核心功能在于能够将Java对象转换成字节流,从而实现对象的持久化存储或是通过网络传输。然而,序列化的应用远不止于此,它还涉及到一...

    关于 Java 对象序列化您不知道的 5 件事

    在本文中,我们将深入探讨关于Java对象序列化你可能不知道的五件事情,这些知识点对于理解和优化你的Java应用程序至关重要。 1. **序列化的意义与用途** Java对象序列化不仅用于持久化对象状态,还能在网络传输中...

    java反序列化利用程序UI版Beta1.1.rar

    1. **Java序列化机制**:Java对象序列化是通过实现`Serializable`接口来标记一个类可被序列化。`ObjectOutputStream`用于将对象写入流,`ObjectInputStream`用于从流中读取并反序列化对象。 2. **易受攻击的库**:...

    Java对象序列化的秘密

    Java对象序列化是Java平台提供的一种机制,允许将对象的状态转换为字节流,以便存储在磁盘上、通过网络传输或在不同时间点恢复。这个过程涉及到将一个复杂的Java对象模型转换为简单的二进制表示,使得数据可以在不同...

    Java Json序列化与反序列化

    本篇文章将深入探讨Java中JSON的序列化与反序列化,以及相关的工具库。 一、JSON概述 JSON是一种独立于语言的数据格式,它的结构简单明了,易于人阅读和编写,同时也容易让机器解析和生成。JSON主要由键值对(key-...

    深入理解Java虚拟机-Java内存区域透彻分析(序列化、反序列化概念及其使用场景+实现序列化的方式+transient关键字)

    Java序列化和反序列化是Java虚拟机中的一种重要机制,它们可以将Java对象转换为二进制数据,然后将其保存到磁盘中或通过网络传输到其他机器上。今天,我们将深入理解Java虚拟机-Java内存区域透彻分析,探讨序列化和...

    深入剖析Java序列化:挑战复杂的面试题与详细解析

    它是Java核心概念的重要组成部分,特别是在面试中,深入理解和熟练掌握Java序列化能够展示出程序员的高级技能。 1. **Java序列化的作用与原理**: - 作用:实现对象的持久化(保存到文件、数据库),以及在网络间...

    Java中的序列化与反序列化.pdf

    Java序列化是Java平台提供的一种持久化机制,它允许我们将Java对象转换成字节流,以便于存储或者在网络中传输。这一过程被称为序列化,而将字节流还原成原来的对象则称为反序列化。在Java中,实现序列化主要通过实现...

    Java中的序列化与反序列化:深入理解与实践指南

    在Java编程中,对象的序列化与反序列化是实现数据持久化和网络传输的关键技术。序列化是将对象的状态转换为字节流的过程,以便可以将其保存到文件、...希望本文能帮助你更好地理解和应用Java中的序列化与反序列化技术。

    如何正确的使用Java序列化技术

    ### 如何正确使用Java序列化技术 #### 技术研究系列 **摘要:** 本文将深入探讨Java序列化技术的各个方面,从基础知识入手,逐步展开对序列化技术机制...希望这些内容能够帮助开发者更好地理解和应用Java序列化技术。

    jackson库实现定制化的java序列化反序列化操作

    标题中的“jackson库实现定制化的java序列化反序列化操作”指的是利用Jackson库的能力,通过自定义规则来控制对象的序列化和反序列化过程。这通常涉及到创建自定义的`JsonSerializer`和`JsonDeserializer`,或者使用...

    java程序,序列化和反序列化操作对文件的运用

    首先,让我们深入理解一下什么是序列化。序列化是将一个对象转换为字节流的过程,这使得我们可以将对象的状态保存到文件或数据库中,或者在网络上传输。在Java中,要使一个类能够被序列化,我们需要让该类实现`java....

Global site tag (gtag.js) - Google Analytics