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

这里不作演示

posted @ 2023-10-27 21:49  rowbed  阅读(14)  评论(0编辑  收藏  举报