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