【Java】Input,Output,Stream I/O流 04 对象流&序列化
对象流,序列化机制
ObjectInputStream
ObjectOutputStream
序列化 对象 写入转 数据 持久化
反序列化 数据 读取转 对象 活化
- 任何实现了Serializable接口的类,其对象可以转化为字节数据,保存和传输时可以还原
- 序列化是RMI [ Remote Method Invoke] 远程方法调用过程的参数和返回值都必须实现的机制
RMI就是JavaEE的基础,所以序列化也是JavaEE的基础
- 实现序列化可以选择两种接口 Serializable Externalizable
持久化与活化
如果持久化多个对象或者属性,那么读取时也需要按照同样的顺序读取
public class SerializableTest { public static void main(String[] args) throws Exception { //persistence(); activation(); } // 对象持久化 static void persistence() throws Exception { // 创建对象流 ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(new File("ObjectStore.txt"))); // 写入对象 objectOutputStream.writeObject(new Person("杰哥",24,true,new String[]{"锐普阿伟","狂笑","尾行"})); // 刷新 objectOutputStream.flush(); // 释放 objectOutputStream.close(); } // 对象活化 static void activation() throws Exception { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File("ObjectStore.txt"))); Object object = objectInputStream.readObject(); if (object instanceof Person) { Person person = (Person) object; System.out.println(person); } objectInputStream.close(); } } // 对象要实现可序列化接口 class Person implements Serializable { String name; Integer age; Boolean gender; String[] hobby; public Person(String name, Integer age, Boolean gender, String[] hobby) { this.name = name; this.age = age; this.gender = gender; this.hobby = hobby; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Boolean getGender() { return gender; } public void setGender(Boolean gender) { this.gender = gender; } public String[] getHobby() { return hobby; } public void setHobby(String[] hobby) { this.hobby = hobby; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", gender=" + gender + ", hobby=" + Arrays.toString(hobby) + '}'; } }
序列版本UID的意义是?
private static final long serialVersionUID = -6849794470754667710L;
假设在没有这个UID的情况下,序列化的类的对象成功持久化写入文件内
而这个对象的类字段或者其他成员发生了改变,再将对象活化时,这个对象无法被识别是出自这个类的对象
UID就是为了确保对象活化时能够正常的被识别出来,而设置的
此外 自定义类中的属性也必须保证是可序列化的(String和基本类型都已经是可序列化的了,要注意是组合自定义类的情况)
序列化无法写入static修饰的和transient修饰的成员变量,值在活化后都为null
序列化实现的总结:
- 1 自定义的类和类中的所有属性必须都是实现了序列化接口的!!![注意自定义的属性]
- 2 声明序列版本UID 确保类在变更字段之前持久化的对象,在活化之后能被Java正常识别
- 3 注意static 和 transient 都不能序列化