java 那些鲜为人知的序列化(debug)

一:起因

Java提供一种机制叫做序列化,其实就是把实体类的对象(Bean对象)以二进制的形式就行存储和传输(读取),多有需要序列化的对象对应的类需要继承 接口 Serializable。

(1)通过有序的格式或者字节序列持久化java对象,其中包含对象的数据,还有对象的类型,和保存在对象中的数据类型。所以,如果我们已经序列化了一个对象,那么它可以被读取并通过对象的类型和其他信息进行反序列化,并最终获取对象的原型。

(2)ObjectInputStream 和 ObjectOutputStream对象是高级别的流对象,包含序列化和反序列化的方法。ObjectOutputStream 拥有很多序列化对象的方法,最常用的是:

(3)那么哪里会需要序列化呢?序列化通常在需要通过网络传输数据,或者保存对象到文件的场合使用。这里说的数据是对象而不是文本。

现在的问题是,我们的网络架构和硬盘都只能识别二进制和字节,而不能识别Java对象。序列化就是把Java对象中的value/states翻译为字节,以便通过网络传输或者保存。另外,反序列化就是通过读取字节码,并把它翻译回java对象

二:示例

(1)员工实体类(Employee.java  是一个bean,内含get set方法)

import java.io.Serializable;
public class Employee implements Serializable{

    int employeeId;
    String employeeName;
    String department;

    public int getEmployeeId() {
        return employeeId;
    }
    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }
    public String getEmployeeName() {
        return employeeName;
    }
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }
    public String getDepartment() {
        return department;
    }
    public void setDepartment(String department) {
        this.department = department;
    }
}

(2)这里以存储在外部文件为例子,外部文件命名为employee.out (文件的读写以employee类的对象进行)

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
 public class SerializeMain {

 /**
  * @author zyp
  */
 public static void main(String[] args) {

  Employee emp = new Employee();
  emp.setEmployeeId(101);
  emp.setEmployeeName("zyp 张燕鹏");
  emp.setDepartment("com.CS");
  Employee emp2 = new Employee();
  emp2.setEmployeeId(102);
  emp2.setEmployeeName("xqz 徐勤柱");
  emp2.setDepartment("中国海洋大学");
  ArrayList<Employee> emps = new ArrayList<Employee>();
  emps.add(emp);
  emps.add(emp2);
  // 以上两个用于测试的
  try
  {
   FileOutputStream fileOut = new FileOutputStream("employee.out",true);
   // employee.ser 这可是文件名称的,相当于序列化的文件名的内的内容的,无法用普通的文本查看器查看的
   ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
   for(int i=0;i<emps.size();i++){
	   outStream.writeObject(emps.get(i));
	   System.out.println(emps.get(i));
   }

   outStream.writeObject(null);// 非常关键的哦,否则报错的peekByte错误的,用于读取的时候判空的
   outStream.close();
   fileOut.close();
  }catch(IOException i)
  {
   i.printStackTrace();
  }
 }
}

(3)读取(2)存储的文件

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;

public class DeserializeMain {
 /**
  * @author zyp
  */
 public static void main(String[] args) {
  ArrayList<Employee> emps = new ArrayList<Employee>();
  Employee emp = null;
       try
       {
          FileInputStream fis =new FileInputStream("employee.out");
          //employee.ser 这可是之前保存的文件名称的,相当于读取序列化的文件名的内的内容的,无法用普通的文本查看器查看的
          ObjectInputStream ois = new ObjectInputStream(fis);
          emp = (Employee) ois.readObject();
//
          while(emp!=null){
        	  emps.add(emp);
        	  emp = (Employee)ois.readObject();
          }
          ois.close();
          fis.close();
       }catch(IOException i)
       {
          i.printStackTrace();
          return;
       }catch(ClassNotFoundException c)
       {
          System.out.println("Employee class not found");
          c.printStackTrace();
          return;
       }
       for(int i=0;i<emps.size();i++){
    	   emp = emps.get(i);
    	   System.out.println("Deserialized Employee...");
           System.out.println("Emp id: " + emp.getEmployeeId());
           System.out.println("Name: " + emp.getEmployeeName());
           System.out.println("Department: " + emp.getDepartment());
           System.out.println(emp);
       }

 }
}

(4)注意事项:

outStream.writeObject(null); (2)中的这一句话,非常关键的哦,否则报错的peekByte错误的,这是用于读取的时候判空的,否者到了文件末尾EOF还在读取employee对象,肯定报错的,错误如下(如果没有这句代码的话)

错误提示

(5)employee.out文件是以16进制进行数据存储的,一般的notepad++文本文件打不开的,UE可以打开的查看16进制代码

(6)eclipse 调试说明:首先打开debug模式(视图)开启,之后设置断点(设置多个断点)

时间: 2024-10-09 08:33:10

java 那些鲜为人知的序列化(debug)的相关文章

Java实现对象的序列化

什么是对象的序列化? 序列化:把对象转化成字节序列的过程就是对象的序列化:反序列化:把字节序列转化成对象的过程就是对象的反序列化.单看概念比较抽象,但是看代码就会明白. 对象序列化的用途 1.Java程序在运行中,对象都是分配在内存中,而序列化的一个用途就是将内存的中对象转化成磁盘中的对象. 2.对象不能直接在网络中传输,有时候需要将对象转成字节序列在网络中传输,这就是对象序列化的第二个用途. 如何实现对象的序列化? 1.新建一个实体对象,实现Serializable接口,这个实体对象就可以进行

Java中的对象序列化

好久没翻译simple java了,睡前来一发.译文链接:http://www.programcreek.com/2014/01/java-serialization/ 什么是对象序列化 在Java中,对象序列化指的是将对象用字节序列的形式表示,这些字节序列包含了对象的数据和信息,一个序列化后的对象可以被写到数据库或文件中,并且支持从数据库或文件中反序列化,从而在内存中重建对象: 为什么需要序列化 序列化经常被用于对象的网络传输或本地存储.网络基础设施和硬盘只能识别位和字节信息,而不能识别Jav

java Serializable和Externalizable序列化反序列化详解--转

一.什么是序列化? “对象序列化”(Object Serialization)是 Java1.1就开始有的特性. 简单地说,就是可以将一个对象(标志对象的类型)及其状态转换为字节码,保存起来(可以保存在数据库,内存,文件等),然后可以在适当的时候再将其状态恢复(也就是反序列化).serialization 不但可以在本机做,而且可以经由网络操作.它自动屏蔽了操作系统的差异,字节顺序等.比如,在 Windows 平台生成一个对象并序列化之,然后通过网络传到一台 Unix 机器上,然后可以在这台Un

JAVA与JSON的序列化、反序列化

package com.linkage.app.memcache; import java.util.HashMap;import java.util.Map.Entry; import net.sf.ezmorph.Morpher;import net.sf.ezmorph.MorpherRegistry;import net.sf.ezmorph.bean.BeanMorpher;import net.sf.json.JSONObject;import net.sf.json.util.JS

动车上的书摘-java对象流与序列化

动车上的书摘-java对象流与序列化 摘要: 摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆木匠 希望转载,保留摘要,谢谢! 钢笔不限贵便宜,书法是来自心对手的交流.-泥沙砖瓦浆木匠 一.对象序列化 当需要存储相同类型的数据,选择固定的长度记录是好选择.但是在面向对象(OOP)程序中,对象之间很少有全部相同的类型.所以,java语言支持一种称为对象序列化(object serialization)的机制. 下面展示一个序列化例子,关于两个对象 Em

java对象流与序列化

Object流,直接把obj写入或读出. 前言: 比如 画图的程序,咣当画一个三角形出来,咣当画一正方形出来.然后存盘,当你下次再打开软件的时候三角形.方块还在原来的位置上.如果用面向对象的思维,三角形,方块都有自己的成员变量,x.y坐标.颜色.线的颜色.粗细等,你存盘的时候要把这些内容写到硬盘上,写到文件里,这叫存盘.比如说一个方块,你存盘的时候只要把起始点的坐标,宽度,高度颜色等等存进去,当再显示的时候再在原处把它画出来. 序列化:把一个object直接转换成字节流写到硬盘上或者写到网络上.

Java对象的XML序列化(转)

转自:http://westlifesz.javaeye.com/blog/48618 java.io.Serializable引发的问题——什么是序列化?在什么情况下将类序列化?  序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化.可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间.序列化是为了解决在对对象流进行读写操作时所引发的问题.序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Seri

java 中类为啥要序列化

java里为什么要序列化?http://zhidao.baidu.com/link?url=7_wAQ8eAl28vcJPE5OKM5Y0Bo4aINNQokHhRmI9XPszEoTO5QF-gNbOTHPzU4e8JMxQ2FYFjU5kuUgtSIPYYN_ 2013-06-19 09:57轻风晓雪 | 浏览 2276 次 编程语言java 1不序列化是二进制流,序列化也是二进制流,有什么不同?最后在计算机里不都是0和1保存嘛?还是说不序列化也可以恶保存,就是没有序列化保存的后好什么的?

Java 深拷贝浅拷贝 与 序列化

一.浅拷贝.深拷贝 浅拷贝会对对象中的成员变量进行拷贝:如果是基本类型,拷贝的就是基本类型的值:如果属性是内存地址(引用类型),拷贝的就是内存地址 : 深拷贝,除了基本类型外,引用类型所引用的对象也会进行拷贝:(引用的对象只要求浅拷贝即可:若要深层拷贝,一般可利用序列化和反序列化来实现,也可手动实现各级引用对象的深层拷贝:) 二.实现: 浅拷贝:实现Cloneable接口,重写clone()方法,在clone()调用父类super.clone()即可: 深拷贝:1. 实现Cloneable接口,