当前位置: 首页 > 后端技术 > Java

Java序列化

时间:2023-04-02 10:28:15 Java

什么是序列化?序列化:将对象信息(对象的类类型、对象的数据、数据的类型)转换成字节序列。通常用于在网络之间传输对象信息或将对象信息存储在磁盘文件(.ser)中。与XML和JSON类似,只是XML和JSON是文本格式,Java序列化是二进制格式。相应地,反序列化就是将二进制字节序列转换为对象的过程。序列化是平台独立的,在一个平台上序列化可以在另一个平台上反序列化。注意:类的方法不会被序列化,因为序列化的两边通常都有类的信息,类的方法不是序列化所必需的。为什么要序列化呢?因为网络架构和硬盘只能理解位和字节,所以需要将Java对象转换成相应的格式进行传输。JDK自带的序列化就是利用JDK来序列化对象。操作是:序列化类实现了java.io.Serializable接口;创建一个ObjectOutputStream输出流,调用输出流的writeObject方法输出序列化后的对象;publicclassEmployeeimplementsSerializable{privatestaticfinallongserialVersionUID=1905122041950251207L;私有字符串名称;...}publicclassMySerialize{publicstaticvoidmain(String[]args){Employeee=newEmployee();/employee.ser");ObjectOutputStreamout=newObjectOutputStream(fileOut);out.writeObject(e);//序列化操作out.close();fileOut.close();}catch(IOExceptioni){i.printStackTrace();}}}使用JDK反序列化对象,操作是:创建一个ObjectInputStream输入流,通过readObject方法反序列化对象;publicclassMyDeserialize{publicstaticvoidmain(String[]args){Employeee=null;尝试{FileInputStreamfileIn=newFileInputStream("/tmp/employee.ser");ObjectInputStreamin=newObjectInputStream(fileIn);//默认的反序列化过程不会调用类构造函数e=(Employee)in.readObject();//反序列化操作在.close();fileIn.close();}catch(IOExceptioni){i.printStackTrace();}catch(ClassNotFoundExceptionc){System.out.println("Employeeclassnotfound");c.printStackTrace();}}}的serialVersionUID字段用于版本控制,在反序列化时用于验证序列化对象的发送方和接收方是否为该对象加载了兼容序列化的类。如果没有声明该字段,JVM会在运行时动态生成一个,所以如果修改了类的结构,比如修改/增加/删除字段,JVM在反序列化的时候会生成一个不同的serialVersionUID。此时,ObjectInputStream的readObject()方法会抛出一个InvalidClassException。但是如果我们声明这个字段,比如privatestaticfinallongserialVersionUID=2L;,那么我们修改类结构后serialVersionUID不会改变,所以不会抛出这个异常。因此,强烈建议每个实现Serializable接口的类都声明这个字段。transient关键字标有transient关键字的字段不能被序列化,同样,静态字段也不能被序列化,因为它们属于一个类而不是一个对象。为什么一个类实现了Serializable接口就可以被序列化?查看ObjectOutputStream的源码,查看writeObject方法,发现它调用了writeObject0方法:/剩余情况if(objinstanceofString){writeString((String)obj,unshared);}elseif(cl.isArray()){writeArray(obj,desc,unshared);}elseif(objinstanceofEnum){writeEnum((Enum)obj,desc,unshared);}elseif(objinstanceofSerializable){writeOrdinaryObject(obj,desc,unshared);}else{if(extendedDebugInfo){thrownewNotSerializableException(cl.getName()+"\n"+debugInfoStack.toString());}else{thrownewNotSerializableException(cl.getName());}}...}可以看到,如果对象是“String,Array,Enum,Serializable”,则可以序列化,否则会抛出NotSerializableException异常。参考资料:什么是序列化?常见的序列化协议有哪些?Java序列化,看完这篇文章就够了Java序列化-菜鸟教程

最新推荐
猜你喜欢