1 java序列化基础
一个类的实例要可以序列化和反序列化,这个类要实现java.io.Serializable 或者 java.io.Externalizable接口,java.io.Serializable只是个标志接口,表示实现该接口的类的时候能被序列化和反序列化。
序列化打印工具类:
/** * 序列化工具类 * @author hehaibo * */ public class SerialUtils { /** * 将序列化对象写入到文件中 * * @param object * 对象 * @param fileName * 文件名 * @throws IOException * @throws FileNotFoundException */ public static void writeObject(Object object, String fileName) throws IOException { FileOutputStream fos = new FileOutputStream(new File(fileName)); ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(new File(fileName))); oos.writeObject(object); oos.flush(); oos.close(); fos.close(); Printer.printf(fileName); } /** * 反序列化一个对象 * @param fileName * @return * @throws IOException * @throws ClassNotFoundException */ public static Object readObject(String fileName) throws IOException, ClassNotFoundException{ Object obj = null; FileInputStream fis = new FileInputStream(new File(fileName)); ObjectInputStream ois = new ObjectInputStream(fis); obj = ois.readObject(); ois.close(); fis.close(); return obj; } }
public class Printer { public static int length=16 ; public static void registerLength(int len){ length=len; } public static void printf(String fileName) throws IOException { File file = new File(fileName); System.out.println("文件大小:" + file.length()); InputStream fis; fis = new FileInputStream(file); byte bs[] = new byte[length]; while ((length = fis.read(bs)) != -1) { System.out.print(Binary2Hex.Bytes2HexString(bs, length) + "\r"); } fis.close(); } }
/** * 二进制转化为十六进制 * * @author wb_haibo.hehb */ public class Binary2Hex { /** * * @param b * byte[] * @return String */ public static String Bytes2HexString(byte[] b, int length) { String ret = ""; // int ia=0xFF; // System.out.println(Integer.toBinaryString(ia)); for (int i = 0; i < length; i++) { // System.out.println(Integer.toBinaryString(b[i])); String hex = Integer.toHexString(b[i] & 0xFF); // if (hex.length() == 2) { hex = "0x" + hex.toUpperCase(); // } if (hex.length() == 3) { hex = hex + " "; } ret += hex + " "; } return ret; } }
序列化示例:
public interface SuperInterface { public static final String abc="abc"; }
public class Person implements Serializable,SuperInterface { public static final String staVal="staVal"; private String name; private String account; private String password; transient private String sex; public Person(){ System.out.println("son come!"); } }
/** * 无继承extentds场景 * 1 增加方法-->方法不会被序列化,因为方法可以通过类的字节码获得。 * 2 增加静态变量-->静态变量不会被序列化,静态变量属于类级别的变量,和类的实例无关 * 3 增加transient[瞬态]的成员变量-->不会被序列化 * 4 增加普通属性--> 会被写入序列化中。 * 5 类实现自定义的接口 [含有公共变量]-->接口中的变量不会被序列化。 * @author hehaibo */ public class TestCaseOne { /** * @param args */ public static void main(String[] args) { try { SerialUtils.writeObject(new Person(), "hehaibo"); Object object = SerialUtils.readObject("hehaibo"); System.out.println(object); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
输出结果:
son come! 文件大小:104 0xAC 0xED 0x0 0x5 0x73 0x72 0x0 0x15 0x6F 0x72 0x67 0x2E 0x68 0x68 0x62 0x2E 0x73 0x65 0x72 0x69 0x61 0x6C 0x2E 0x50 0x65 0x72 0x73 0x6F 0x6E 0x62 0x4D 0x55 0x76 0x9B 0xA8 0x3 0xBD 0x2 0x0 0x3 0x4C 0x0 0x7 0x61 0x63 0x63 0x6F 0x75 0x6E 0x74 0x74 0x0 0x12 0x4C 0x6A 0x61 0x76 0x61 0x2F 0x6C 0x61 0x6E 0x67 0x2F 0x53 0x74 0x72 0x69 0x6E 0x67 0x3B 0x4C 0x0 0x4 0x6E 0x61 0x6D 0x65 0x71 0x0 0x7E 0x0 0x1 0x4C 0x0 0x8 0x70 0x61 0x73 0x73 0x77 0x6F 0x72 0x64 0x71 0x0 0x7E 0x0 0x1 0x78 0x70 0x70 0x70 0x70 org.hhb.serial.Person@1df073d
序列化的子类继承示例:
public class Person extends SuperClasss implements Serializable{ public static final String staVal="staVal"; private String name; private String account; private String password; transient private String sex; public Person(){ // super("abc"); System.out.println("son come!"); } } public class SuperClasss implements Serializable,SuperInterface{ private String test="test"; public SuperClasss(){ System.out.println("old father come 1!"); } // public SuperClasss(String name){ // System.out.println("old father come 2!"); // } }
/** * 场景: * 1 序列化的子类继承不实现序列化的父类<br> * 1.1 子类提供默认的构造函数,父类提供默认构造函数<br> * 序列化时会调用父类的默认构造函数,父类的普通域不会被序列化<br> * * 原因分析: * * 反序列化时:会调用父类默认的构造函数。 * * 1.2 子类提供默认的构造函数,父类提供非默认的构造函数,子类未调用父类被覆盖的构造函数<br> * 编译错误,提示要调用父类的构造函数,这也是java的基础,构造函数隐含super()<br> * * 1.3 子类提供默认的构造函数,父类提供非默认的构造函数,子类的构造函数中调用父类被覆盖的构造函数<br> * 运行时错误, java.io.InvalidClassException: org.hhb.serial.Person; org.hhb.serial.Person; no valid constructor<br> * * 原因分析: * * 1.4 子类提供默认的构造函数,父类的提供默认构造函数,也提供其他构造函数<br> * 序列化时会只调用父类的默认构造函数,父类的普通域不会被序列化<br> * * 反序列化时:同1.1,会调用父类默认的构造函数。 * * 2 序列化的子类继承实现序列化的父类<br> * * 序列化时不会调用 父类的构造函数,父类的普通域会写入序列化 * 反序列化时,也不会调用父类的构造函数,也不会调用子类的构造函数 * 原因分析: * */ public class TestCaseTwo { /** * @param args * @throws IOException * @throws ClassNotFoundException */ public static void main(String[] args) throws IOException, ClassNotFoundException { SerialUtils.writeObject(new Person(), "zhangsan"); Object o = SerialUtils.readObject("zhangsan"); System.out.println(o); SerialUtils.readObject("zhangsan"); } }
待续...
Externalizable继承 Serializable接口,增加了2个方法.
public interface Externalizable extends java.io.Serializable { void writeExternal(ObjectOutput out) throws IOException; void readExternal(ObjectInput in) throws IOException, ClassNotFoundException; }
相关推荐
【Protocol Buffer序列化对比Java序列化】 Protocol Buffer(简称PB)是Google开发的一种高效的数据序列化协议,而Java序列化是Java平台内置的一种序列化机制。两者的主要目标都是将对象转化为字节数组,便于在网络...
总的来说,protobuf是Java序列化的一个强大工具,尤其在处理大量数据交换和跨平台通信时,它的效率和灵活性使它成为首选。学习和掌握protobuf不仅可以提升项目性能,还能提高代码的可维护性和扩展性。
### Java序列化原理与算法详解 #### 序言 在现代软件开发中,尤其是在网络通信和数据持久化领域,对象的序列化与反序列化扮演着至关重要的角色。Java作为一种广泛应用的编程语言,提供了强大的内置支持来实现序列化...
### Java序列化(Serializable)的作用与反序列化详解 #### 一、序列化是什么? 序列化是指将程序中的对象转换为字节流的过程,从而方便存储或传输这些对象。通常,序列化用于将对象的状态(即其实例变量的值,而非...
Java序列化是Java平台中的一项重要技术,它允许对象的状态被转换为字节流,以便存储或通过网络进行传输。这种技术在分布式系统、持久化存储以及数据交换等场景中非常常见。本资源包含了三个流行的Java序列化框架:...
标题中的“WEB漏洞-反序列化之PHP&JAVA全解(下)”指的是关于Web应用程序安全领域的一个重要话题,即PHP和JAVA平台上的反序列化漏洞。反序列化漏洞是由于程序在处理序列化数据时没有充分验证输入,从而允许攻击者构造...
### Java序列化的机制和原理 #### 一、序列化与反序列化概念 在Java中,序列化(Serialization)指的是将对象的状态信息转换为可以存储或传输的形式的过程。通常,对象的状态信息会被转换成一系列的字节,这些字节...
### Java序列化与反序列化的深入解析 #### 序列化的功能与意义 序列化是Java编程语言中的一项核心功能,其主要目的是将对象的状态转换为可以存储或传输的格式,便于持久化保存或网络传输。序列化并不涉及对象的...
Java反序列化安全漏洞是一种严重的安全威胁,它主要发生在Java程序处理序列化数据时。序列化是Java中的一种机制,可以将对象状态转换为字节流,以便存储或传输。反序列化则是将字节流恢复为Java对象的过程。 在Java...
每个可序列化的类都有一个与之关联的`serialVersionUID`,它是用于版本控制的标识符。当类的结构(如字段)发生变化时,`serialVersionUID`应相应更新。如果不匹配,反序列化时会抛出`InvalidClassException`。可以...
### Java反序列化实战知识点详解 #### 一、反序列化概述 - **定义**:在计算机科学领域,反序列化是指将字节流或文本流等数据转换回其原始对象结构的过程。这一过程通常与序列化相对应,序列化是将对象的状态转化...
这通常涉及到对Java序列化格式的深入理解以及对 ysoserial 工具的熟悉,ysoserial 是一个用于生成Java反序列化payload的工具。 0x04 应用场景 这种探测技术在以下场景中非常有用: 1. 黑盒安全审计:在不知道目标...
Java序列化是指将对象的状态信息转换为可以存储或传输的形式的过程。相反,反序列化则是在适当的时候把这个流转换回原对象的过程。当应用程序接收来自不受信任源的数据并进行反序列化时,可能触发安全漏洞。例如,...
"Java序列化技术的探讨" Java序列化技术是Java中的重要技术,在RMI、AJAX、Web Service等方面都有应用。本文将介绍几种常用的Java序列化技术,并通过比较、分析这些技术在功能、序列化后的字节数和序列化、反序列化...
Java 中序列化 NotSerializableException 问题是 Java 开发中常见的问题之一。 NotSerializableException 是 Java 中的一个异常,它发生在尝试序列化一个不implement Serializable 接口的对象时。今天,我们将讨论 ...
总之,Java序列化和反序列化库对于开发人员来说是不可或缺的工具,Gson作为其中的一个优秀库,提供了简单而强大的功能,使得Java对象与JSON之间的转换变得轻松快捷。正确理解和使用这类库,可以极大地提高开发效率和...
Java反序列化是一种将已序列化的对象状态转换回对象的过程,通常用于持久化数据或在网络间传输对象。在Java中,这一过程通过实现Serializable接口并在需要时调用ObjectInputStream的readObject()方法来完成。然而,...
XStream是一个强大的Java库,它允许...XStream的灵活性和易用性使其成为Java开发者的首选工具之一。不过,需要注意的是,序列化和反序列化时的安全问题,尤其是当处理不受信任的数据时,应避免反序列化潜在的恶意对象。