Java拾贝第十二天——IO流之对象序列化与对象流
把一个对象转换为二进制流就是对象的序列化。(对象👉二进制流)
二进制流转换为一个对象就是对象的反序列化。(二进制流👉对象)
二进制流也就是byte[]数组
如果一个类的对象想要被序列化,则这个类必须要实现java.io.Serializable接口。
该接口定义如下:
public interface Serializable {
//内部没有任何需要重写的方法,仅给JVM作一个标记。实现该接口的类可以被序列化。
}
至此,一个可以被序列化的类栗子:
class ObTest implements Serializable{
private String name;
private int age;
public ObTest() {
}
public ObTest(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "ObTest{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
以上的ObTest类以及实现了Serializable接口,所以此类的对象可以被流式传输。
想要完成对象的输入或输出,必须依靠对象流。
对象流分为对象输出流(ObjectOutputStream)和对象输入流(ObjectInputStream)。
对象输出流
对象输出流主要作用是把一个对象转换为二进制流。其构造方法如下:
public ObjectOutputStream(OutputStream out) throws IOException
ObjectOutputStream常用方法如下:
方法 | 类型 | 描述 |
---|---|---|
public void writeObject(Object obj) throws IOException | 普通方法 | 把一个对象转换为二进制流 |
D:\IOtest\text.txt内:
//空
栗子:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
ObTest obTest = new ObTest("张三", 18);
try {
ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream(file));
stream.writeObject(obTest);
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
程序运行后,D:\IOtest\text.txt内:
sr moudle2.ObTest拊咤 I ageL namet Ljava/lang/String;xp t 寮犱笁
没错,就是这么些不可读的东西。其本身不可以直接修改!否则会被破坏,导致无法反序列化。
对象序列化后只有属性保存了下来。也就是只有属性会被序列化。
对象输入流
对象输入流主要作用把二进制流转换为一个对象。其构造方法如下:
public ObjectInputStream(InputStream in) throws IOException
ObjectInputStream常用方法如下:
方法 | 类型 | 描述 |
---|---|---|
private final Object readObject(Class<?> type) throws IOException, ClassNotFoundException | 普通方法 | 读取二进制流,返回一个对象 |
普通方法 |
D:\IOtest\text.txt内:
sr moudle2.ObTest拊咤 I ageL namet Ljava/lang/String;xp t 寮犱笁
栗子:
public static void main(String[] args) {
File file = new File("D:" + File.separator + "IOtest" + File.separator + "text.txt");
try {
ObjectInputStream stream = new ObjectInputStream(new FileInputStream(file));
ObTest o = (ObTest) stream.readObject();//把返回的类强转为ObTest
System.out.println(o);
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
程序运行结果:
ObTest{name='张三', age=18}
System.out.println()输出一个类时会默认调用其toString()方法。
注意
如果某个属性不想被序列化可以使用关键字transient
栗子:
class ObTest implements Serializable {
private String name;
private transient int age;//该属性不会被序列化
public ObTest() {
}
public ObTest(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "ObTest{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
如果想根据自己的需要选择被序列化的属性,则可以使用另一种序列化接口——Externalizable
这里不作演示