java IO流 序列化流
java提供了一种序列化机制,一个字节序列可以表示为一个对象,相当于对象存储到文件中去了,具有持久化。反序列化,从字节序列文件里面把重构成对象。
protected | ObjectOutputStream() 为完全重新实现ObjectOutputStream的子类提供一种方法,不必分配刚刚被ObjectOutputStream实现使用的私有数据。 |
| ObjectOutputStream(OutputStream out) 创建一个写入指定的OutputStream的ObjectOutputStream。 |
Modifier | Constructor and Description |
---|---|
protected | ObjectInputStream() 为完全重新实现ObjectInputStream的子类提供一种方法,不必分配刚刚被ObjectInputStream实现使用的私有数据。 |
| ObjectInputStream(InputStream in) 创建从指定的InputStream读取的ObjectInputStream。 |
序列化
如果是序列化集合,集合元素的对象也需要实现Serializable接口
public class Test {
public static void main(String[] args) {
/**
* java.io.ObjectOutputStream类继承OutputStream,所以该类也表示字节输出流
* 序列化操作:
* void writeObject(Object obj)
* 将指定的对象写入ObjectOutputStream。
* 注意:
* 被序列化的对象必须实现Serializable接口
*/
Student zhangsan = new Student("张三", 18);
try (
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("IO流\\aaa\\zhangsan.txt"));
){
objectOutputStream.writeObject(zhangsan);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
反序列化
注意事项:
1,对于jvm可以反序列化对象,它是必须要能找到class文件的类(在项目下的out目录下面)
2,能找到class文件的类,但是class文件在序列化对象后发生了修改,那么也会报异常。
我们在序列化的时候,会自动生成一个序列化id。如何解决呢?在属性中加上static final long serialVersionUID = 42L;
这样如果对象文件改了,还是会用原来的对象反序列化。
public class Test2 {
/**
* 反序列化
* Object readObject()
* 从ObjectInputStream读取一个对象。
*/
public static void main(String[] args) {
try (
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("IO流\\aaa\\zhangsan.txt"));
){
Student zhangsan = (Student)objectInputStream.readObject();
System.out.println(zhangsan.getName());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
如果一个对象的属性不想被序列化,那么就使用transient关键字标明为瞬态。如下,这个时候我们反序列化后,获取age属性,发现值是默认值null
public class Student implements Serializable {
private String name;
private transient Integer age;
public Student() { }
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(name, student.name) && Objects.equals(age, student.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}