- 解释
- 实现方式
- 关于静态变量
解释
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
用途
1)把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;(可以存放在想使用的扩展名文件中)
2)在网络上传送对象的字节序列。
意义:使得对象可以脱离程序的运行而独立存在。
序列化:将对象写入到IO流中
反序列化:从IO流中恢复对象
实现方式
如果需要将某个对象保存到磁盘上或者通过网络传输,那么这个类应该实现Serializable接口或者Externalizable接口之一。
Serializable是一个空接口,一个接口里面什么内容都没有,我们可以将它理解成一个标识接口。在Java中的这个Serializable接口其实是给jvm看的,通知jvm,我不对这个类做序列化了,你(jvm)帮我序列化就好了。
序列化api:
java.io.ObjectOutputStream
代表对象输出流,writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream
代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
public class Student implements Serializable{
private String name;
private int id;
static String school="东坡路小学";
public student(String name,int id,String school) {
this.name=name;
this.id=id;
this.school=school;
}
@Override
public String toString() {
return "name is "+name+" id is"+id+" school"+school;
}
}
public class Serialization {
public static void main(String[] args) {
student std=new student("aaa",5464,"后宰门");
System.out.println(std);
try {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("data.txt"));
oos.writeObject(std);
System.out.println("finsh");
oos.close();
}catch (Exception e) {
e.printStackTrace();
}
try {
ObjectInputStream ois =new ObjectInputStream(new FileInputStream("data.txt"));
std=(student)ois.readObject();
System.out.println(std);
ois.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}
结果:
name is aaa id is5464 school后宰门
finsh
name is aaa id is5464 school后宰门
注意:
在创建继承Serralizable的接口类当中不可以使用非瞬态字段。
例如:在上述的student类当中不可以有Scanner input=new Scanner(System.in)的字样,无论这个Scanner是否使用。
transient关键字用于指示字段不应该是序列化(这意味着保存, 比如文件)过程的一部分。例如在有些程序中用户的姓名密码是希望隐藏的,因此不可以作为序列化的一部分。(但是很少使用这个关键字)
关于静态成员的问题
静态成员属于类级别的,所以不能序列化,序列化只是序列化了对象而已。
上述输出是改变后的变量是因为测试都在同一个机器(而且是同一个进程),因为这个jvm已经把school加载进来了,所以获取的是加载好的school,如果是传到另一台机器或者关掉程序重新写个程序读入data.txt,此时因为别的机器或新的进程是重新加载school的,所以i信息就是初始时的信息,即东坡路小学。