前段时间同事发布了一个日常,发布OK之后观察没有问题,但是下午有个团队就照过来了,说是我们传递过去的消息发序列化失败,查了很长时间,最后定位是hession的版本存在冲突,以前是hession的3.x版本,应用中依赖了另外一个jar包,这个jar包简介依赖了hession的4.x版本,所以序列化出现问题,所以这篇文章打算扫盲一下。
通过网络传输的对象(网络接口上的参数、返回值类型、会抛出的异常类),必须实现Serializable接口,或者父类已经实现序列化接口。
java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的“深复制”,即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。
java 序列化比较简单,通常不需要编写保存和恢复对象状态的定制代码。实现java.io.Serializable接口的类对象可以转换成字节流或从字节流恢复,不需要在类中增加任何代码。只有极少数情况下才需要定制代码保存或恢复对象状态。这里要注意:不是每个类都可序列化,有些类是不能序列化的,例如涉及线程的类与特定JVM有非常复杂的关系。
序列化机制:
序列化分为两大部分:序列化和反序列化。 序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型
转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例。ObjectOutputStream中的序列化过程与字节流连接,包括对象类型
和版本信息。反序列化时,JVM用头信息生成对象实例,然后将对象字节流中的数据复制到对象数据成员中。
如果你写过类实现了Serializable 接口,那肯定收到过这样的警告提示,“The serializable class xxx does not declare a static final
serialVersionUID field of type long”
SerrialVersionUID被用来作为序列化类的版本控制,如果你没有明确的生命序列化ID,那么JVM会根据类中的信息自动的为你生成一个。但是这个默认的ID对于class文件的比较敏感,且可能在不同的JVM中不同,有可能在反序列化的时候出现异常。如果没有显式赋值,也在你看不见觉察不到的情况下,在你增减了field/修改了定义的情况下,serialVersionUID已被改变,这时网络两端就对接不上而悲剧了。没定义serialVersionUID,而又发生了serialVersionUID变化,网络两端只有所有机器都停掉,并且先后起有顺序时,才能不出丝毫差错。
如果一个类没有序列化,通过ObjectOuputStream进行写操作(),会抛出异常信息“java.io.NotSerializableException”。
例如下面代码:
FileOutputStream fs = new FileOutputStream(new File("d:\\java.txt"))
ObjectOutputStream oos = new ObjectOutputStream(fs);
oos.writeObject(user);
读取序列化之后的文件,
InputStream input = new FileInputStream(new File("d:\\java.txt"));
ObjectInputStream ois = new ObjectInputStream(input);
UserDO user = (UserDO)ois.readObject();
Externalizable实现了Serializable接口,如果一个类实现了Externalizable接口,则累的序列化以及发序列化则由自己完全控制。这时候在通过Object 进行序列化的时候,会调用类自己实现的writeExternal()以及readExternal()方法。
序列化时,类的所有数据成员应可序列化,除了声明为transient的成员。将变量声明为 transient类型就是告诉JVM成员变量dtToday将不被序列化。将数据成员声明为transient后,序列化过程就无法将其加进对象字节流中。后面数据反序列化时,要重建数据成员(因为它是类定义的一部分),但dtToday将不包含任何数据,因为这个数据成员不向流中写入任何数据。
不要序列化大数据对象/十分复杂对象,一般long/int/String/Map/List/Array等常见类组成的对象就已能解决问题,最好不要在本应用的业务接口传递/返回另一人主导业务/结构的对象。
不是建议不要用ArrayList,只是要注意ArrayList经过网络后可能顺序不一样。两需一一对应的List,经过网络后不一定一一对应。List中有零星的null,可能会给别人造成麻烦。
分享到:
相关推荐
Java中的序列化(serialization)机制能够将一个实例对象的状态信息写入到一个字节流中,使其可以通过socket进行传输、或者持久化存储到数据库或文件系统中;然后在需要的时候,可以根据字节流中的信息来重构一个...
16. **java.io**:I/O流相关的类,用于文件读写、数据序列化和网络通信。 17. **java.lang**:基础类库,包括Object、String、Math等核心类,以及反射和异常处理。 18. **java.lang.annotation**:支持注解的类和...
76、什么是java序列化,如何实现java序列化? 18 77、简述synchronized和java.util.concurrent.locks.Lock的异同 ? 18 78、abstract class Name { private String name; public abstract boolean isStupidName...
在Java中,数组是一种对象,可以容纳固定大小的同类型元素序列。了解和掌握Java数组的相关知识点对于任何Java程序员来说都是至关重要的。 1. **数组定义** Java数组的定义语法如下: ```java 数据类型[] 数组名 ...
类加载器 ClassLoader 反射 Stream 流 函数式编程 Lambda 表达式 网络编程-协议 网络编程-端口 网络编程-IP 多线程 IO流-字节流 IO流-字符流 IO流-转换流 File Map HashMap 序列化和反序列化 可变参数 类型通配符 ...
4. **文件I/O流编程**:读写文件、数据序列化等。 5. **网络编程**:TCP/IP协议的应用,如客户端/服务器模型。 6. **多线程编程**:利用多线程提高程序性能。 #### Java EE基础知识 1. **Java面向对象编程**:与...
### Java编程规范详解 #### 一、概述 Java作为一种广泛使用的面向对象的编程语言,在软件开发领域占据着举足轻重的地位。为了提高代码的质量、可读性和可维护性,制定一套合理的Java编程规范是非常必要的。本文将...
4. **IO流**:介绍输入/输出流的概念,包括文件操作、字节流、字符流、对象序列化等。这部分内容涉及数据的读写和传输。 5. **网络编程**:讲解Socket编程,如何创建客户端和服务器进行网络通信,以及HTTP、HTTPS...
本资源摘要信息将为您提供一份详细的 Java 面试指南,涵盖了 Java 基础知识、集合框架、多线程、JVM、Java 面向对象编程、异常处理、IO 流、序列化和 Java 集合框架等方面的知识点。 一、Java 基础知识 1. Java 语...
10. **输入输出流**:讲述I/O流的概念,包括文件读写、对象序列化和反序列化,以及使用BufferedReader和PrintWriter等类。 11. **多线程**:介绍并发编程的基础,如Thread类的使用、synchronized关键字、wait()、...
- 编写通用工具类:如日志、序列化、测试工具等,需要处理各种未知类型的对象。 总结,Java反射机制是Java平台灵活性和动态性的体现,它极大地扩展了Java程序的能力,但同时也需要谨慎使用,平衡好其带来的便利和...
7. **输入/输出流**:解释Java的I/O系统,包括文件操作、流的概念、缓冲区和对象序列化。 8. **多线程**:探讨并发编程,线程的创建、同步、死锁问题,以及java.util.concurrent包提供的高级并发工具。 9. **Java ...
这里会涉及字节流、字符流、缓冲流和对象序列化。 6. **多线程**:Java支持并发编程,多线程思维导图会讲解线程的创建、同步机制(如synchronized关键字、wait()、notify()方法)、线程池以及并发集合类。 7. **...
8. **输入输出流**:介绍I/O流的概念,包括文件读写、对象序列化、网络流等。 9. **多线程**:讲解并发编程的基础,包括Thread类的使用、同步机制(synchronized关键字、wait/notify机制)和并发工具类。 10. **...
6. **输入/输出流**:介绍I/O流的概念,如字节流和字符流,以及文件操作、对象序列化和缓冲区的使用。 7. **泛型**:讲解泛型的基本概念,其在集合和方法中的应用,以及通配符和边界限制。 8. **枚举和注解**:...
6. **输入输出流**:介绍I/O流的概念,包括文件操作、对象序列化以及网络流的使用。 【Java进阶内容】 1. **多线程**:深入理解线程的创建和管理,包括同步机制(synchronized关键字、wait/notify方法)和并发工具...
5. **输入输出与文件操作**:讲解Java I/O流的概念,如何进行文件读写、网络通信和数据序列化,为实际项目开发打下基础。 6. **多线程**:介绍线程的创建、同步和通信,包括线程池和并发工具类,让开发者能够编写...
7. **输入输出流**:讲解I/O流的基本概念,File类,字节流,字符流,缓冲流,对象序列化等。 8. **集合框架**:涵盖ArrayList、LinkedList、HashSet、HashMap等容器类的使用,以及泛型概念。 9. **多线程**:介绍...
5. **输入/输出(I/O)**:讲解流的概念,包括文件I/O、网络I/O和NIO(非阻塞I/O),以及如何进行数据序列化和反序列化。 6. **反射与注解**:解释反射机制,如何在运行时动态获取类信息并操作对象,以及注解的使用和...
5. **输入/输出流**:讨论文件I/O、对象序列化和网络通信中的数据传输。 6. **多线程**:包括线程的创建、同步和通信,以及线程池的使用。 7. **反射机制**:解释如何在运行时动态获取类的信息并操作对象,这对于...