java中提供很方便的将对象转换成byte数组用于进行文件输出,网络传输等目的———序列化
今天由于被一个序列化的小问题折磨了2小时,于是决定做个总结,以备不时之需。
序列化的实现很简单,只要在声明class的时候 implements Serializable即可。
实现此接口的类就可以被序列化,并最终用writeObject方法进行输出。
反之,反序列化的时候使用readObject()将byte【】转化会原有对象。
当处理对象数组时,比如arraylist,可以直接用writeObject(数组名)将整个数组输出,
java会替你做好一切,前提条件是这个类已经实现了Serializable接口,并且类中没有不可实例化的对象。
也就是说,如果这个类中还包含别的类的实例,那么被调用的类也需要实现Serializable接口。
今天遇到的问题就是属于类中含有不可序列化的对象,造成整个序列化失败:
报错信息如下:
java.io.NotSerializableException: java.util.Scanner
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at java.util.ArrayList.writeObject(ArrayList.java:570)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1469)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at billxpress.Main.writeToFile(Main.java:110)
at billxpress.Main.main(Main.java:68)
从报错代码上看,其实可以很明白了看出错误的根源:
java.io.NotSerializableException: java.util.Scanner 因为我在要被序列化的类中声明了全局对象Scanner 用于控制台的读取,
而Scanner 是不能被序列化的,于是出错。解决方法是,将scanner放到需要用到它的方法内即可。
当类中有部分信息不希望被序列化的时候,可以用transient标记,序列化是将跳过此变量。