【总结】Java序列化,反序列化实例(属性类不实现序列化接口)

简介:

序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

Java中String, Integer的父类都实现了序列化接口


Person类实现了序列化接口,Person中的所有属性也必须实现序列化接口,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package  serialize;
import  java.io.Serializable;
 
/**
  * <p>ClassName: Person<p>
  * <p>Description:测试对象序列化和反序列化<p>
  * @author 巧克力黑
  * @version 1.0 V
  * @createTime 2016-03-18
  */
public  class  Person  implements  Serializable {
 
     /**
      * 序列化ID
      */
     private  static  final  long  serialVersionUID = -5809782578272943999L;
     private  String name;
     private  Pet pet;
     
     public  Person(String name, String sex,  int  age, Pet pet) {
         this .name = name;
         this .pet = pet;
     }
 
     public  String getName() {
         return  name;
     }
 
     public  void  setName(String name) {
         this .name = name;
     }
 
     public  Pet getPet() {
         return  pet;
     }
 
     public  void  setPet(Pet pet) {
         this .pet = pet;
     }
}

Pet类,也是Person中的一个属性,此处Pet没有实现Serializable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package  serialize;
/**
 
  * @author 巧克力黑
  * @version 1.0 V
  * @createTime 2016-03-18
  *
  */
class  Pet{
     private  String name;
     public  Pet(String name) {
         this .name = name;
     }
     public  String getName() {
         return  name;
     }
     public  void  setName(String name) {
         this .name = name;
     }
     @Override
     public  String toString() {
         return  this .name;
     }
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package  serialize;
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileNotFoundException;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.ObjectInputStream;
import  java.io.ObjectOutputStream;
import  org.slf4j.Logger;
import  org.slf4j.LoggerFactory;
/**
  * <p>ClassName: TestSerializeAndDeserialize<p>
  * <p>Description: 测试对象的序列化和反序列<p>
  * @author 巧克力黑
  * @version 1.0 V
  * @createTime 2016-03-18
  */
public  class  TestSerializeAndDeserialize {
     private  static  Logger logger = LoggerFactory.getLogger(TestSerializeAndDeserialize. class );
     
     public  static  void  main(String[] args)  throws  Exception {
         serializePerson(); //序列化Person对象
         Person p = deserializePerson(); //反序列Perons对象
         logger.info( "name={},pet={}" , p.getName(),p.getPet().toString());
     }
     
     private  static  void  serializePerson()  throws  FileNotFoundException,
             IOException {
         Person person =  new  Person( "qiaokeli" "男" 25 new  Pet( "旺财" ));
         
         //ObjectOutputStream 对象输出流,将Person对象存储到E盘的Person.txt文件中,完成对Person对象的序列化操作
         ObjectOutputStream oo =  new  ObjectOutputStream( new  FileOutputStream( new  File( "E:/Person.txt" )));
         oo.writeObject(person);
         logger.info( "将Person序列化到文件" );
         oo.close();
     }
     private  static  Person deserializePerson()  throws  Exception, IOException {
         ObjectInputStream ois =  new  ObjectInputStream( new  FileInputStream( new  File( "E:/Person.txt" )));
         Person person = (Person) ois.readObject();
         logger.info( "反序列化Person对象" );
         return  person;
     }
}

在Pet没有实现Serializable接口的情况下,看看控制台运行错误

1
2
3
4
5
6
7
8
9
Exception in thread  "main"  java.io.NotSerializableException: serialize.Pet
     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java: 1183 )
     at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java: 1547 )
     at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java: 1508 )
     at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java: 1431 )
     at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java: 1177 )
     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java: 347 )
     at serialize.TestSerializeAndDeserialize.serializePerson(TestSerializeAndDeserialize.java: 36 )
     at serialize.TestSerializeAndDeserialize.main(TestSerializeAndDeserialize.java: 25 )

FindBugs提示错误

1
2
3
Bug: Class serialize.Person defines non- transient  non-serializable instance field pet
This Serializable  class  defines a non-primitive instance field which is neither  transient , Serializable, or java.lang.Object, and does not appear to implement the Externalizable  interface  or the readObject() and writeObject() methods.  Objects of  this  class  will not be deserialized correctly  if  a non-Serializable object is stored in  this  field.
Rank: Troubling ( 14 ), confidence: HighPattern: SE_BAD_FIELD Type: Se, Category: BAD_PRACTICE (Bad practice)

结论:

由于Person中的Pet属性没有实现序列化接口serializable,在执行序列化,反序列化过程中就会出错。

解决办法就是将Pet也实现序列化接口。




     本文转自巧克力黒 51CTO博客,原文链接:http://blog.51cto.com/10120275/1752503,如需转载请自行联系原作者






相关文章
|
2天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
1月前
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
143 57
|
3天前
|
JSON Java Apache
Java基础-常用API-Object类
继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。
|
1月前
|
Java
在Java中实现接口的具体代码示例
可以根据具体的需求,创建更多的类来实现这个接口,以满足不同形状的计算需求。希望这个示例对你理解在 Java 中如何实现接口有所帮助。
87 38
|
6天前
|
数据采集 JSON Java
利用Java获取京东SKU接口指南
本文介绍如何使用Java通过京东API获取商品SKU信息。首先,需注册京东开放平台账号并创建应用以获取AppKey和AppSecret。接着,查阅API文档了解调用方法。明确商品ID后,构建请求参数并通过HTTP客户端发送请求。最后,解析返回的JSON数据提取SKU信息。注意遵守API调用频率限制及数据保护法规。此方法适用于电商平台及其他数据获取场景。
|
11天前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
43 6
|
22天前
|
JSON 前端开发 JavaScript
Java属性为什么不能是is开头的boolean
在Java实体类中,阿里规约要求boolean属性不应以is开头。文章通过实际案例分析了isUpdate字段在JSON序列化过程中变为update的问题,并提供了自定义get方法或使用@JSONField注解两种解决方案,建议遵循规约避免此类问题。
Java属性为什么不能是is开头的boolean
|
1月前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
52 8
|
28天前
|
Java API
Java中内置的函数式接口
Java中内置的函数式接口
25 2
|
1月前
|
Java
在Java中如何实现接口?
实现接口是 Java 编程中的一个重要环节,它有助于提高代码的规范性、可扩展性和复用性。通过正确地实现接口,可以使代码更加灵活、易于维护和扩展。
68 3