首页 / JAVA / Java中的序列化与反序列化
Java中的序列化与反序列化
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java中的序列化与反序列化,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5853字,纯文字阅读大概需要9分钟。
内容图文
序列化:序列化后的对象变成与平台无关的二进制流,可以保存到磁盘中,可以在网络中进行传输。该二进制流被其他的程序获取之后可以将其进行反序列化恢复成原来的java对象。
对象序列化的机制:是java语言内建的一种对象持久化方式 ,通过对象序列化可以将对象保存为字节数组,该字节数组同样可以保存到磁盘中或者通过网络传输。对象序列化可以和容易的在JVM的活动对象和字节数组(数据流)之间进行转化。
序列化相关的类和接口:
Java.io.Serilizable
Java.io.Externalizable
ObjectOuput
ObjectOutputStream
ObjectInput
ObjectInputStream
- 实现使用Serializable接口进行序列化
没有实现该接口的类将无法使其任何状态序列化或反序列化。如果想要对一个不支持Serialiable接口的对象进行反序列化,会抛出NotSerializableException。如果要序列化的类有父类,想要将父类中定义的变量持久化,需要父类集成Serializable接口。
使用对象流实现序列化
反序列化机制无须通过构造器来初始化java对象。如果使用序列化机制向文件中写入多个java对象,使用反序列化机制恢复对象时必须按实际写入的顺序读取。当一个可序列化类有多个父类时包括它的直接父类和间接父类,这些父类要么有无参的构造器,要么也是可序列化的,否则就会抛出InvalidClassException异常。如果父类是不可序列化的,但是存在无参的构造器,则该父类中定义的Field的值不会序列化到二进制流中。
对象引用的序列化
在一个可序列化的类A对象中存在另外一个类B对象的引用,想要正常恢复A对象,程序会将B对象进行序列化,因此类B必须是可序列化的,否则类A不可序列化。
当使用java序列化机制序列化可变对象时,只有第一次 调用的writeObject()方法来输出对象时,才会将对象转换成字节序列,并写入到ObjectOutStream,在后面程序中即使该对象的Field发生了改变,再次调用writeObject()方法输出该对象时,改变后的Field也不会输出。
简单的实例1:
import lombok.Data; import java.io.Serializable; @Data public class UserTest implements Serializable { private String name; private String age; private Long ids; private Clothes clothes; private User user; } |
import lombok.Data; import java.io.Serializable; import java.util.List; @Data public class User extends UserTest implements Serializable { private List<Clothes> clothesList; } |
import lombok.Data; import java.io.Serializable; import java.math.BigDecimal; @Data public class Clothes implements Serializable{ private BigDecimal price; private String product; private String material; private String season; } |
import java.io.*; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; public class SerializableTest { public static void main(String[] args){ try { File file = new File("F:\\serializableTest\\serializableTest.txt"); ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file)); User user = new User(); user.setName("二二分"); user.setAge("21"); List<Clothes> clothes = new ArrayList<>(); Clothes clothes1 = new Clothes(); clothes1.setMaterial("纯棉"); clothes1.setPrice(BigDecimal.valueOf(40L)); clothes.add(clothes1); user.setClothesList(clothes); outputStream.writeObject(user); UserTest userTest = new UserTest(); userTest.setAge("12"); userTest.setName("挤房间分"); outputStream.writeObject(userTest); outputStream.close(); ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(file)); User user1 = (User) inputStream.readObject(); UserTest userTest1 = (UserTest) inputStream.readObject(); System.out.println(user1); System.out.println("name:"+user1.getName()+"/age:"+user1.getAge()); System.out.println(userTest1); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
输出结果:
User(clothesList=[Clothes(price=40, product=null, material=纯棉, season=null)]) name:二二分/age:21 UserTest(name=挤房间分, age=12, ids=null, clothes=null, user=null) |
实例2:
import lombok.Data; @Data public class UserTest{ private String name; private String age; private Long ids; private Clothes clothes; private User user; } |
import lombok.Data; import java.io.Serializable; import java.util.List; @Data public class User extends UserTest implements Serializable { private List<Clothes> clothesList; } |
import lombok.Data; import java.io.Serializable; import java.math.BigDecimal; @Data public class Clothes implements Serializable{ private BigDecimal price; private String product; private String material; private String season; } |
import java.io.*; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; public class SerializableTest { public static void main(String[] args){ try { File file = new File("F:\\serializableTest\\serializableTest.txt"); ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file)); User user = new User(); user.setName("二二分"); user.setAge("21"); List<Clothes> clothes = new ArrayList<>(); Clothes clothes1 = new Clothes(); clothes1.setMaterial("纯棉"); clothes1.setPrice(BigDecimal.valueOf(40L)); clothes.add(clothes1); user.setClothesList(clothes); outputStream.writeObject(user); ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(file)); User user1 = (User) inputStream.readObject(); System.out.println(user1); System.out.println("name:"+user1.getName()+"/age:"+user1.getAge()); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
出参结果:
User(clothesList=[Clothes(price=40, product=null, material=纯棉, season=null)]) name:null/age:null |
Externalizable 接口
该接口继承了Serialiable ,该接口中定义了两个抽象的方法,writeExternal()与readExternal()。开发人员需要重写这两个方法,如果没有在两个方法中定义序列化的实现细节,反序列化输出的内容为空。使用Externalizable接口进行序列化的时候,在读取对象时,会调用被序列化类的无参构造器去创建一个新的对象,然后再将被保存的对象的字段 的值分别填充到新对象中。因此实现该接口的类必须提供一个public的无参的构造器。如果没有无参的构造器,运行时会抛出异常。
ObjectOutputStream类和ObjectInputStream类,通常使用这两个类来将一个对象进行持久化以及从持久化存储中把对象读取出来。因此:writeObject()方法存储Field的顺序应该和readObject()方法中恢复Field的顺序一致,否则将不能正常恢复该java对象。
内容总结
以上是互联网集市为您收集整理的Java中的序列化与反序列化全部内容,希望文章能够帮你解决Java中的序列化与反序列化所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。