这几天在看到设计模式时,看到有关于序列化的知识,发现自己之前这块知识很欠缺,所以这花了两天仔细研究了一下,感觉这个东西还是很有趣的(当然也很有用-。+),今天给大家带来这篇文章,希望对大家有帮助。
序列化概念和应用
首先我们需要知道序列化是个什么意思。
- 序列化:将对象转换为可传输的二进制流的过程。
- 反序列化:把字节序列恢复成对象的过程。
我举个栗子:我们都进行过文件操作吧。我们在文件中写数字,或者写汉字,再或者写英文,这些东西都是可以直接转为二进制字节的,我们把需要的数据存储在File中,实现了数据存储到设备中,实现了数据持久化。
但是现在我有一个对象需要暂时存储到文件中,这个跟刚才的基本类型不一样了哦。所以说怎么办?
还有这个情况:我们在进行网络传输,传输账号、密码等,这些都是基本数据。那我如果想传输一个对象过去呢?到了对方电脑上之后,鬼知道你这是个什么东西。。。。
根据这两种案例,相信大家已经对序列化的应用有所了解了,主要可以分为以下几类:
- 存储到文件或本地数据库(如SQLite)这类持久化数据操作。
- 通过网络请求传输对象。
- 内存中数据调用(Intent,下面会多次用到)。
一句话概括,就是对象进行存储和传递的一种方法:转化为二进制流。
而进行序列化主要有两个重要的类:Serializable类和Parcelable类。我们分别来看一下。
Serializable类
首先说一下这个类,相信在Java中大家可能已经见到过这个类了。这里简单介绍一下:
public interface Serializable {
}
Serializable是一个标记接口,从上面的类中也可以看出来,他是一个空的接口。
我们传输时候,各种各样的类,我们需要有一个类来对他们进行统一。但是Java中是单根继承,而接口恰好弥补了这个地方。我们可以将实现的借口看做父类,这样通过Serializable类就实现了多种类的统一,同时为类打上了标签,可以通过instanceof Serializable判断是否能序列化(个人理解)。
而它使用起来也很简单,只将需要序列化的类实现Serializable类就好了,其他的我们完全不用操作。
Serializable在Java中就有了,我们先来看一下在Java中它是如何使用:
Java中使用Serializable
盗取了一张大神的图,我们在学习IO流中,有两个类是用于读写对象的——ObjectInputStream和ObjectOutputStream。
ObjectOutputStream负责将内存中的对象写入存储中。ObjectInputStream负责从本地存储中读取存入的对象。而是用这两个类,那么传入的这个类必须是序列化的。我们看一下代码就知道了:
import java.io.Serializable;
public class StudentBean implements Serializable{
private int age;
private String name;
private int id;
public StudentBean(int age, String name, int id) {
super();
this.age = age;
this.name = name;
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "StudentBean [age=" + age + ", name=" + name + ", id=" + id + "]";
}
}
这是一个Bean类,实现了get和set方法,构造方法和重写了toString方法。
public static ObjectOutputStream serilizeData(StudentBean studentBean) {
ObjectOutputStream objectOutputStream = null ;
try {
objectOutputStream = new ObjectOutputStream(
new FileOutputStream(
new File("/Users/jibai/Desktop/" + StudentBean.class.getSimpleName() + ".txt")
)
);
objectOutputStream.writeObject(studentBean);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return objectOutputStream;
}
这是我们将序列化的Bean类通过类输入流写入文件的方法。
public static StudentBean reverseSerilizeData(String path) {
StudentBean bean = null;
try {
ObjectInputStream objectInputStream = new ObjectInputStream(
new FileInputStream(
new File(path)
)
);
bean = (StudentBean) objectInputStream.readObject();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bean;
}
这个是将本地存储对象的文件读取出来的方法。
最后看一下main方法:
public static void main(String[] args) {
// TODO Auto-generated method stub
serilizeData(new StudentBean(18, "tom", 01));
StudentBean bean = reverseSerilizeData("/Users/jibai/Desktop/" + StudentBean.class.getSimpleName() + ".txt");
System.out.println(bean.toString());
}