我发布了一个疑问,即我读到了 Effective Java。如果这是一个真正简单直接的疑问,我深表歉意。所以在第 74 条 - 明智地实现 Serializable中,他是说即使在使用私有和包私有字段在您的类上实现了良好的信息隐藏之后,它也容易失去效力?无论我过去读到什么,序列化所做的都是将对象转换为字节流形式,并在反序列化后保留相同的对象。在这个过程中它是如何丢失数据隐藏的?
3 回答
您可能可以使用序列化和反序列化访问对象内部状态的值。
通过序列化一个对象,您可能能够读取您不应该读取的私有字段的值。相反,如果您创建一个精心设计的字节数组并将其反序列化为一个实例,您可能能够将其初始化为非法状态。
@candiru 指出了在 OOP 上下文中序列化的数据隐藏问题。
但是序列化还有另一个方面。
您可以通过网络发送序列化文件,以便可以窥视它,并且可以轻松破坏本应是私有的东西。
下面是我序列化的 Bean 类的内容(使用默认技术)。我可以通过在文本编辑器中打开序列化文件来查看内容。
’ sr SerializationPractice1 I ageL extrat Ljava/lang/String;L nameq ~ xp
pt SidKumarq ~ x
现在,您甚至可以在不了解课程的情况下轻松找到以下内容:
- 课程名称:SerializationPractice1
- 名为名称值的字符串属性是SidKumar
这些事情你肯定会注意到;其他细节不是很清楚。以上信息是正确的。
我确实相信序列化有可能将私人数据暴露给外界。这就是外部化(使用 Externalizable 类型实例非常方便)的地方。通过实现 Externalizable 接口的 writeExternal(...) 方法,开发人员可以完全控制序列化过程,而不是完全依赖默认的序列化运行时实现。下面是我的想法的伪代码(我会忽略实际的方法签名,因为它只是一个旨在表达更广泛想法的伪代码):
class SensitiveData implemets java.io.Externalizable{
int sensitiveInteger;
writeExternal (OutputData outputData){
//encrypt sensitiveInteger here
//serialize the sensitiveInteger which is now encrypted to any persistent store
outputData.writeInt(sensitiveInteger);
//do other processing
}
}
事实上,为什么只是加密,如果我们想要在要序列化的实例是“大”的某些情况下,我们可能希望将序列化的字节压缩到某个持久存储。