序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
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,如需转载请自行联系原作者