当创建对象时,程序运行时它就会存在,但是程序停止时,对象也就消失了.但是如果希望对象在程序不运行的情况下仍能存在并保存其信息,将会非常有用,对象将被重建并且拥有与程序上次运行时拥有的信息相同。可以使用对象的序列化。
对象的序列化: 将内存中的对象直接写入到文件设备中
对象的反序列化: 将文件设备中持久化的数据转换为内存对象
基本的序列化由两个方法产生:一个方法用于序列化对象并将它们写入一个流,另一个方法用于读取流并反序列化对象。
ObjectOutput
writeObject(Object obj)
将对象写入底层存储或流。
ObjectInput
readObject()
读取并返回对象。
下面介绍的就是他们的实现子类:ObjectOutputStream和ObjectInputStream
对象的输入输出流:对象的输入输出流的主要作用是:用于对象信息的读写,对象信息一旦写到文件上那么对象的信息就可以持久化
对象的输出流
ObjectOutputStream 主要用用于输出对象
ObjectOutputStream的使用步骤
1、找到目标文件
2、建立数据的输出流通道,需要准备一个FileOutputStream流
3、建立对象的输出流通道
4、把对象写出去
5、关闭资源
使用反序列化,就是使用流ObjectInputStream流,完全和上面相反的步骤。
对象输入输出流使用需要注意的细节:
1、如果对象需要被写出到文件上,那么对象所属的类必须要实现Serializable接口,Serializable接口没有任何的方法,是一个标志接口。
2、对象的反序列化和对象的克隆,创建对象的时候,并不会调用构造方法。
3、serialVersionUID是用于记录class文件的版本信息的,serialVersionUID这个数字是通过一个类的类名,成员,包名,工程名算出来的一个数字。
4、使用ObjectInputStream反序列化的时候,ObjectInputStream会先读取文件中的serialVersionUID与本地的serialVersionUID对比,如果不一致反序列化失败
5、如果反序列化的时候可能会修改类的成员,那么最好一开始就给这个类,指定一个serialVersionUID,如果一个类已经指定了serialVersionUID,然后在序列化和反序列化的时候,jvm都不会自己计算这个class的serialVersionUID了。这样就不怕无法序列化和反序列化了。点击累前面的黄色箭头,添加一个serialVersionUID
6、如果一个对象的某个数据不想序列化到硬盘上,可以使用关键字transient修饰
7、如果一个类,维护了另外一个类的引用,另外一个类,也需要实现Serializable接口。如果无法修改这个类的源码,可以给这个类创建一个可序列化的子类。如果这个类是final的也就是不可以继承的。那么就在使用trancint关键字,或者是指定serialVersionUID。
下面是一个简单的例子:
1 class Address implements Serializable 2 { 3 String country; 4 String city; 5 6 public Address(String country, String city) 7 { 8 this.country = country; 9 this.city = city; 10 } 11 } 12 13 14 class User implements Serializable{ 15 16 private static final long serialVersionUID = -1241976087141510667L; 17 18 String userName ; 19 20 String password ; 21 22 transient int age; 23 24 Address address; 25 26 public User(String name, String pass) 27 { 28 this.userName = name; 29 this.password = pass; 30 } 31 32 public User(String name, String pass, int age, Address address) 33 { 34 this.userName = name; 35 this.password = pass; 36 this.age = age; 37 this.address = address; 38 } 39 40 @Override 41 public String toString() 42 { 43 return "用户名:"+this.userName+" 密码:"+this.password+" 年龄:"+this.age+" 地址:"+this.address.city; 44 } 45 } 46 47 48 public class Demo3 49 { 50 public static void main(String[] args) throws IOException, ClassNotFoundException 51 { 52 //把user的信息持久化 53 /*User user = new User("admin", "123"); 54 System.out.println(user); 55 */ 56 writeObj(); 57 readObj(); 58 59 } 60 61 //把文件中的对象信息取出来 62 public static void readObj() throws IOException, ClassNotFoundException 63 { 64 File file = new File("D:\users.txt"); 65 FileInputStream fileInputStream = new FileInputStream(file); 66 //建立对象的输入流对象 67 ObjectInputStream inputStream = new ObjectInputStream(fileInputStream); 68 //读取独对象信息 69 User user = (User) inputStream.readObject(); //创建对象坑定要依赖对象所属的class文件 70 System.out.println(user); 71 } 72 73 74 //定义方法把对象的信息写到硬盘上------>对象的序列化 75 public static void writeObj() throws IOException 76 { 77 Address address = new Address("China", "Anhui"); 78 User user = new User("admin", "123", 15, address); 79 80 //1、找到目标文件 81 File file= new File("D:\users.txt"); 82 //建立数据的输出流对象 83 FileOutputStream fileOutputStream = new FileOutputStream(file); 84 //建立对象的输出流对象 85 ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); 86 //把对象写出去 87 objectOutputStream.writeObject(user);//序列化house的内容 是给JVM看的 一般我们是看不懂的 88 //关闭资源 89 objectOutputStream.close(); 90 } 91 92 }