对于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设计人员为了安全起见,不允许所有的对象都能序列化,而是要用户编码的时候去指定可以序列化的类。
如果一个对象需要序列化,但是又有一些私密信息不想持久化呢?(例如单独将我们person的secret属性屏蔽持久化)
大家可以使用static或者transient修饰变量,具体怎么用呢?请移步happyjava同学的blog。 谢谢大家的阅读,以上是我个人看法,如有更多的看法可以评论一起交流。