为什么Java序列化要实现Serializable

栏目: Java · 发布时间: 6年前

内容简介:对于Serializable,大家都知道是java中的一个读到这里或许有很多同学会产生疑问:一个空接口,里面啥都没有。为什么java设计的时候一定要实现Serializable才能序列化?不能去掉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。 谢谢大家的阅读,以上是我个人看法,如有更多的看法可以评论一起交流。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

智能革命

智能革命

李彦宏 等 / 中信出版集团 / 2017-5-1 / 68.00元

人类历史上的历次技术革命,都带来了人类感知和认知能力的不断提升,从而使人类知道更多,做到更多,体验更多。以此为标准,李彦宏在本书中将人工智能定义为堪比任何一次技术革命的伟大变革,并且明确提出,在技术与人的关系上,智能革命不同于前几次技术革命,不是人去适应机器,而是机器主动来学习和适应人类,并同人类一起学习和创新这个世界。“人工智能”正式写入2017年政府工作报告,折射出未来人工智能产业在我国经济发......一起来看看 《智能革命》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

html转js在线工具
html转js在线工具

html转js在线工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换