为何Java序列化要实现Serializable

(本内容是我在搜集一些资料后的我的感悟,若有问题,请指出。蟹蟹)java

背景

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

疑问

读到这里或许有不少同窗会产生疑问:网络

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

解答

笔者经过对网络上的答案进行浏览,虽然大部分都是解释Serializable的做用,没有说为何要这样。可是最终仍是找到一个比较有说服力的解释。post

总的就是说安全性问题,具体缘由看法释:假如没有一个接口(即没有Serializable来标记是否能够序列化),让全部对象均可以序列化。那么全部对象经过序列化存储到硬盘上后,均可以在序列化获得的文件中看到属性对应的值(后面将会经过代码展现)。因此最后为了安全性(即不让一些对象中私有属性的值被外露),不能让全部对象均可以序列化。要让用户本身来选择是否能够序列化,所以须要一个接口来标记该类是否可序列化。this

证实

首先咱们先创建一个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的对象序列化存入硬盘啦。spa

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设计人员为了安全起见,不容许全部的对象都能序列化,而是要用户编码的时候去指定能够序列化的类。code


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

你们可使用static或者transient修饰变量,具体怎么用呢?请移步happyjava同窗的blog。 谢谢你们的阅读,以上是我我的见解,若有更多的见解能够评论一块儿交流。

相关文章
相关标签/搜索