概念
什么是序列化?为什么要序列化?我之前也是一直弄不清楚。只知道如果对象作为流进行远程传输时,就需要把这个对象序列化。现在看来,其实没必要死扣概念。只需要知道在什么时候用,怎么用就行。太概念的解释我也不会,我今天要讲的就是应用场景和怎么用
应用场景
1.远程传输
之前刚学了java RMI远程调用接口,这回就用到了。看代码:
IHello hello = new HelloImpl();
/*
在主机ip上创建并提供一个“注册表”实例,用来接收指明“端口”的请求
*/
LocateRegistry.createRegistry(8888);
/*
给一个远程对象重新绑定一个“给定”的名字
@param name:必须为一个URI形式
这个方法会覆盖之前已经绑定的名字
*/
java.rmi.Naming.rebind("rmi://127.0.0.1:8888/hello", hello);
System.out.print("Ready")
远程端代理一个对象hello
,对象有个方法public String sayHello(Girl girl)
。客户端调用服务器上的对象,调用其方法sayHello
,就需要传入一个Girl对象作为参数。如下:
IHello hello = (IHello) Naming.lookup("rmi://127.0.0.1:8888/hello");
Girl girl = new Girl("李雷",25);
System.out.println("调用远程对象,开始交谈:"+hello.sayHello(girl));
当我不加Serializable时,运行,报错(对象没有实例化):
调用远程对象失败,原因是:error marshalling arguments; nested exception is:
java.io.NotSerializableException: rmi.bean.Girl
2.对象流
当我们需要把一个对象写入文件,或者从文件中读入一个对象时,我们会用到ObjectOutputStream这个流。这是就需要把对象序列化
public static void main(String[] args) throws Exception {
FileOutputStream fileOutputStream = new FileOutputStream(new File("S:Girl.txt"));
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
FileInputStream fileInputStream = new FileInputStream(new File("S:Girl.txt"));
Girl girl = new Girl("韩梅梅",25);
objectOutputStream.writeObject(girl);
}
看报错信息:
Exception in thread "main" java.io.NotSerializableException: rmi.bean.Girl
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at io.TestSerializable.main(TestSerializable.java:23)
怎么序列化
对象序列化很简单,就是实现Serializable接口即可。至于serialVersionUID这个属性,不写也会有默认的。所以不用在意非得写这个序列号id
public static void main(String[] args) throws Exception {
FileOutputStream fileOutputStream = new FileOutputStream(new File("S:Girl.txt"));
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
FileInputStream fileInputStream = new FileInputStream(new File("S:Girl.txt"));
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Girl girl = new Girl("韩梅梅",25,"女");
objectOutputStream.writeObject(girl);
Girl girl1 = (Girl) objectInputStream.readObject();
System.out.println(girl1);
}
我用ObjectOutputStream.writeObject(girl)把对象写道Girl.txt,并用girl=ObjectOutputStream.readObject()把文件中对象的数据读入到girl对象(即jvm内存中)。
看下结果:
Girl{sex='女', name='韩梅梅', age=25}
反序列化
反序列就是要把文件中的数据写入java 对象中。如girl=ObjectOutputStream.readObject()就是反序列化。
对ObjectOutputStream思考
起初对ObjectOutputStream不怎么了解,以为写道文件中的数据是json格式。在打开文件是才发现是乱码。开始以为是字符集不对。后来网友大神说:
文件中存储的是字节流,并非文字
这才恍然大悟。当我再用girl=ObjectOutputStream.readObject()导入对象,并输出时,发现输出的结果并没有乱码。这才明白。