java 基础之 I/O流 其四 (对象流和序列化)
程序员文章站
2022-07-09 23:03:28
...
对象流和序列化
java语言支持一种称为对象序列化的非常通用的机制,可以将任何对象写出到流总,并在之后将其读回。
使用场景:进程之间的通讯时,对象可以和数据一样以二进制的形式在网络上传送。我的天啊~
要实现这样的场景,要先了解序列化,和对象流
1. 序列化
什么是序列化和反序列化?:
Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。
为什么要序列化?:
作用1:实现了数据持久化,通过序列化,就可以把数据永久地保存在硬盘上(通常是在文件里面),因为原来是在内存中,当程序退出、断电时,数据就没有了。
作用2:利用序列化实现远程通讯,即在网络上传送对象的字节序列。
如何实现Java序列化与反序列化?:
实现Serializable或Externalizable接口的类的对象才能被序列化。
(Externalizable 是 Serializable的子接口,可以只序列化一部分属性)
下面的代码是两种序列化的方式
//Serializable 是一个没有方法的 接口,为了标识序列化
public class Person implements Serializable{
private String name;
private int age;
public Person(){}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
//Externalizable 继承于 Serializable 必须实现两个方法
public class People implements Externalizable{
private String eat;
private String language;
public String getEat() {
return eat;
}
public void setEat(String eat) {
this.eat = eat;
}
public String getLanguage() {
return language;
}
@Override
public String toString() {
return "People{" +
"eat='" + eat + '\'' +
", language='" + language + '\'' +
'}';
}
public void setLanguage(String language) {
this.language = language;
}
//重点是这里
//只序列化部分属性
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(eat);
out.writeObject(language);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.eat = (String) in.readObject();
this.language = (String) in.readObject();
}
}
当然,为了实现序列化 要和对象流结合起来使用
2.对象流
通过实现Serializable 的类 使用对象流
public class ObjectTestStream {
public static void main(String[] args) {
ObjectTestStream ots = new ObjectTestStream();
//Serializable 序列化
ots.getSerializable();
//Externalizable 序列化
ots.getExternalizable();
}
//Serializable 序列化
public void getSerializable() {
Person person = new Person();
person.setAge(18);
person.setName("xiaobai");
//和使用普通的流一样
try(ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("emplyes.dat"))){
//输出
out.writeObject(person);
} catch (Exception e) {
e.printStackTrace();
}
try(ObjectInputStream is = new ObjectInputStream(new FileInputStream("emplyes.dat"))){
//读取
Person s = (Person) is.readObject();
System.out.println(s.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
//Externalizable 序列化
public void getExternalizable() {
People people = new People();
people.setEat("吃饭");
people.setLanguage("中国话");
//这里和 实现Serializable 对象的一样 方法去生成对象流
try(ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(new File("emplyes2.dat")))){
oos.writeObject(people);
} catch (Exception e) {
e.printStackTrace();
}
try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("emplyes2.dat")))){
//当然这里会因为 Externalizable 序列化多少属性而决定
People p = (People) ois.readObject();
System.out.println(p.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}