转载

为什么Java序列化要实现Serializable

对于Serializable,大家都知道是java中的一个 接口 。用来标记是否可序列化,该接口中什么都没有。网上大部分都只是告诉我们,使用该接口可以使对象序列化,从而可以便于 存储和传输 。而如果不实现该接口,则在序列化的时候会抛出异常。

疑问

读到这里或许有很多同学会产生疑问:

一个空接口,里面啥都没有。为什么java设计的时候一定要实现Serializable才能序列化?不能去掉Serializable这个接口,让每个对象都能序列化吗?

解答

笔者通过对网络上的答案进行浏览,虽然大部分都是解释Serializable的作用,没有说为什么要这样。但是最终还是找到一个比较有说服力的解释。

总的就是说安全性问题,具体原因见解释:假如没有一个接口(即没有Serializable来标记是否可以序列化),让所有对象都可以序列化。那么所有对象通过序列化存储到硬盘上后,都可以在序列化得到的文件中看到属性对应的值(后面将会通过代码展示)。所以最后为了安全性(即不让一些对象中私有属性的值被外露),不能让所有对象都可以序列化。要让用户自己来选择是否可以序列化,因此需要一个接口来标记该类是否可序列化。

证明

首先我们先建立一个 person 类,该类有三个属性:一个年纪(我愿意告诉别人),一个姓名(我愿意告诉别人),一个秘密(我不愿意告诉别人)。具体代码如下。

public class Person implements Serializable {

    private int age;
    private String name;
    //我的秘密
    private String secret;

    public Person(int age, String name, String secret) {
        this.age = age;
        this.name = name;
        this.secret = secret;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person() {
    }
}
复制代码

然后就是我们将这个Person的对象序列化存入硬盘啦。

public class Main {
    public static void main(String[] args) {
        /**
         * person对象有三个属性,
         * 一个是我的年纪(可以让别人知道)
         * 一个是我的名字(可以让别人知道)
         * 一个是我的秘密(我不想告诉别人)
         */
        Person person = new Person(22, "小明", "我喜欢畅畅");
        // 把对象存入硬盘
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person"));){
            oos.writeObject(person);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
复制代码

执行这段代码后,会在项目目录下发现一个person文件。然后大家会发现有些对象的值竟然是明文存在里面。例如 我喜欢畅畅 这是我的秘密鸭。

为什么Java序列化要实现Serializable

所有如果什么对象都可以序列化的话,那么对象的一些私有属性都有可能被恶意代码获取的阔能。所以呢,java设计人员为了安全起见,不允许所有的对象都能序列化,而是要用户编码的时候去指定可以序列化的类。

如果一个对象需要序列化,但是又有一些私密信息不想持久化呢?(例如单独将我们person的secret属性屏蔽持久化)

大家可以使用static或者transient修饰变量,具体怎么用呢?请移步happyjava同学的blog。 谢谢大家的阅读,以上是我个人看法,如有更多的看法可以评论一起交流。

原文  https://juejin.im/post/5d0db8186fb9a07ed136dde3
正文到此结束
Loading...