`
crazy_rabbit
  • 浏览: 34621 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

对象的序列化和反序列化——笔记二

阅读更多

继续“对象的序列化和反序列化”:

如果希望进一步控制对象的序列化和反序列化的方式,步骤如下:

  1. 我们可以在以上的User类中提供一个readObject()和writeObject()方法。
  2. 当ObjectOutputStream(对象输出流)对一个对象进行序列化时,如果该对象具有writeObject()方法,那么就执行这个方法,否则就按默认的方式序列化。
  3. 在writeObject()方法中,可以调用ObjectOutputStream的defaultWriteObject()方法,使得对象输出流执行默认序列化操作。
  4. 当ObjectInputStream(对象输入流)对一个对象进行反序列化的时候,如果该对象具有readObject()方法,那么就执行这个方法,否则就按默认的方式反序列化。
  5. 在readObject()方法中,可以调用ObjectInputStream的defaultReadObject()方法,使得对象的输入流执行默认的反序列化操作。

 

例如修改后的Java类:为User类提供了writeObject()和readObject()方法,使得被transient关键字修饰的password属性能够进行特殊的序列化。在writeObject()方法中先对name属性进行了默认的序列化,接着把password属性进行加密后再序列化,具体办法为获得password属性的字节数组,把数组中的每个字节的二进制位取反,再把取反后的字节数组写到对象输出流中。

package safe;
import java.io.*;
public class User implements Serializable {
  private String name;
  private transient String password;
  public User(String name, String password) {
    this.name=name;
    this.password=password;
  }
  public String toString() {
    return name + " " + password;
  }
  
  /** 加密数组,将buff数组中的每个字节的每一位取反 
   *  例如13的二进制为00001101,取反后为11110010
   */
  private byte[] change(byte[] buff){
    for(int i=0;i<buff.length;i++){
      int b=0;
      for(int j=0;j<8;j++){
        int bit=(buff[i]>>j & 1)==0 ? 1:0;
        b+=(1<<j)*bit;
      }
      buff[i]=(byte)b;
    }
    return buff;
  }

  private void writeObject(ObjectOutputStream stream)throws IOException {
    stream.defaultWriteObject();  //先按默认方式序列化 
    stream.writeObject(change(password.getBytes()));
  }
  private void readObject(ObjectInputStream stream)
          throws IOException, ClassNotFoundException {
    stream.defaultReadObject();  //先按默认方式反序列化
    byte[] buff=(byte[])stream.readObject();
    password = new String(change(buff));
  }
  public static void main(String[] args) throws Exception{
    User user = new User("Tom", "123456");
    System.out.println("Before Serialization:" + user);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
   
    //把User对象序列化到一个字节缓存中
    ObjectOutputStream o =new ObjectOutputStream(buf);
    o.writeObject(user);
      
    //从字节缓存中反序列化User对象
    ObjectInputStream in =new ObjectInputStream(
          new ByteArrayInputStream(buf.toByteArray()));
    user= (User)in.readObject();
    System.out.println("After Serialization:" + user);
   }
}

 

在User对象序列化的数据中,保存了password属性的加密数据,在反序列化过程中,会把password的加密数据再恢复到password属性。以上程序的打印结果为:

Before Serialization:weidong tomcat
After Serialization:weidong tomcat
 

 

0
0
分享到:
评论

相关推荐

    Java学习笔记——良葛格

    2. **类与对象**:Java是面向对象的语言,因此理解类和对象至关重要。笔记会介绍类的定义、对象的创建与使用,以及封装、继承和多态等面向对象特性。 3. **数组与集合框架**:数组是存储固定数量同类型数据的结构,...

    《剑指Offer》刷题笔记——面试题37. 序列化二叉树

    《剑指Offer》是面试题集中的经典之作,其中第37题——“序列化二叉树”是一个常被问到的问题,旨在考察开发者对于数据结构和递归算法的理解。本题要求实现一个二叉树的序列化和反序列化功能,即能够将二叉树的结构...

    Java JDK 6学习笔记——ppt简体版

    笔记将涵盖FileInputStream、FileOutputStream、BufferedReader、BufferedWriter等基本流类,以及文件操作和对象序列化。 6. **多线程**:Java支持多线程编程,通过Thread类和Runnable接口可以创建并管理线程。了解...

    Go 学习笔记——雨痕

    方法和接口是Go语言面向对象编程的两个关键概念。方法是与特定类型关联的函数,它们可以访问该类型的具体值。接口是一组方法的集合,任何类型实现了接口的所有方法就是实现了该接口。并发是Go语言的核心特性之一,它...

    sv笔记——system——verilog笔记_超详细

    2. **队列、动态和关联数组**:减少了内存消耗并自带搜索和分类功能。 3. **类和结构**:支持抽象数据结构,增强了代码的模块性和可维护性。 4. **联合和合并结构**:允许对同一数据有多种视图,增强了灵活性。 5. *...

    网络运维笔记——T221.pdf

    - **序号和确认号**:用于数据的序列化和确认,确保数据的有序和无损传输。 - **首部长度**:记录数据段的大小,包括首部和数据部分。 - **控制位**:如 URG、ACK、PSH、SYN、RST、FIN,分别用于紧急数据、确认、...

    【达内】听课笔记之二——JAVA

    Java I/O系统包括文件I/O、网络I/O和对象序列化。java.io包提供了一系列类用于读写文件,如FileReader、FileWriter;java.net包处理网络通信,如Socket、ServerSocket;java.io.ObjectInputStream和java.io....

    JAVA 私塾笔记整理——反射机制(Reflection)

    它允许我们获取类的信息(如类名、方法名、属性等),并能在运行时创建和调用类的对象,甚至可以访问私有成员,这在很多场景下都非常有用,比如插件系统、序列化、框架开发等。 2. **Class类** 在Java中,`java....

    Oracle学习笔记——day04

    在Oracle学习笔记的第四天,我们探讨了数据库管理和操作的一些核心概念,主要集中在DDL(数据定义语言)、DML(数据操作语言)、DCL(数据控制语言)以及事务管理。以下是对这些内容的详细阐述: 首先,我们看到了...

    JavaBean讲解(上)——代码+笔记

    本教程的“JavaBean讲解(上)——代码+笔记”会进一步展示如何创建和使用JavaBean,通过具体的代码示例和详细解释,帮助你掌握JavaBean的编写和应用。笔记部分可能包括关键知识点的总结、常见问题及解决策略,以及...

    C#6.0学习笔记——从第一行C#代码到第一个项目设计(第二个包)

    开发环境搭建、语法基础、面向对象编程、类型转换、字符串处理与数学运算、控制台应用程序、变体的应用、集合与泛型、调试与单元测试、Lambda表达式、LINQ查询语句、Windows窗体应用程序、WPF基础知识、多线程与异步...

    WebService的实现——CXF学习笔记

    使用了`@XmlAccessorType(XmlAccessType.FIELD)`和`@XmlType(name = "User")`注解,表明这个类是XML序列化的,字段将映射到XML元素。 5. **XML配置**:CXF可以通过XML配置文件(如`cxf-servlet.xml`)来配置服务...

    批处理脚本学习笔记——程序员版.pdf

    扩展批处理功能是一个高级话题,本笔记中讲解了如何通过批处理模拟数组和对象,以及如何嵌入PHP或Perl代码来扩展批处理的功能,这使得批处理脚本可以处理更复杂的任务。 在批处理任务实战部分,文档举了网站部署的...

    WebService另一种轻量级实现—Hessian 学习笔记.rar

    1. **序列化与反序列化**:Hessian提供了高效的序列化和反序列化机制,能够将Java对象转换为字节流,然后在网络上传输。到达目的地后,这些字节流再被反序列化回原来的对象。这种机制大大减少了数据传输的开销。 2. ...

    python笔记——擒蟒之路

    理解如何使用print()函数及其参数,如字符串连接、格式化输出,对于调试和输出信息是十分必要的。 “变量保留字”是Python中具有特殊含义的词汇,如if、else、for等,不能用作自定义变量名,否则会导致语法错误。...

    XStream笔计rar.rar

    2. **反序列化**:将XML字符串转换回对象,使用`fromXML()`方法。 ```java YourObject yourObject = (YourObject) xstream.fromXML(xml); ``` 四、配置与自定义 XStream允许用户进行广泛的配置,包括命名空间...

    Gson解析的Bean不能混淆.zip_java gson 防止混淆

    在Java开发中,Gson库是一个非常常用的JSON序列化和反序列化库,它使得Java对象和JSON数据之间的转换变得简单。然而,在Android开发中,当我们进行代码混淆时,可能会遇到Gson解析的Bean不能混淆的问题。这个问题...

    MLDn学习笔记 —— JDK新特性(枚举)

    4. 自动序列化:枚举类型自动支持Java的序列化机制。 三、枚举的方法 1. `values()`:返回枚举类型的全部常量数组,常用于遍历枚举。 2. `valueOf(String)`:根据字符串查找对应的枚举常量,若不存在则抛出`...

    严蔚敏——数据结构笔记

    首先,数据是信息的载体,是计算机能够识别、存储和处理的对象。数据元素是数据的基本构成单元,它可能包含多个数据项,每个数据项是具有独立意义的最小标识单位。数据结构则是数据元素之间的相互关系,也就是数据的...

Global site tag (gtag.js) - Google Analytics