Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么时候可以使用ObjectInputStream.readUnshared()和.readObject()?_Java_Oracle_Java 7_Objectinputstream_Objectoutputstream - Fatal编程技术网

Java 什么时候可以使用ObjectInputStream.readUnshared()和.readObject()?

Java 什么时候可以使用ObjectInputStream.readUnshared()和.readObject()?,java,oracle,java-7,objectinputstream,objectoutputstream,Java,Oracle,Java 7,Objectinputstream,Objectoutputstream,Java ObjectInputStream中有两种类似的方法: 及 文件规定: public Object readUnshared()抛出IOException,ClassNotFoundException 从ObjectInputStream读取“非共享”对象。此方法与readObject相同,只是它防止对readObject和readUnshared的后续调用返回对通过此调用获得的反序列化实例的其他引用。具体而言: 如果调用readUnshared来反序列化反向引用(之前已写入流的对

Java ObjectInputStream中有两种类似的方法:

文件规定:

public Object readUnshared()抛出IOException,ClassNotFoundException

从ObjectInputStream读取“非共享”对象。此方法与readObject相同,只是它防止对readObject和readUnshared的后续调用返回对通过此调用获得的反序列化实例的其他引用。具体而言:

如果调用readUnshared来反序列化反向引用(之前已写入流的对象的流表示),将抛出ObjectStreamException

如果readUnshared成功返回,则任何后续尝试反序列化对readUnshared反序列化的流句柄的引用都将导致抛出ObjectStreamException

通过readUnshared反序列化对象会使与返回对象关联的流句柄无效。注意,这本身并不总是保证readUnshared返回的引用是唯一的;反序列化对象可以定义readResolve方法,该方法返回对其他方可见的对象,或者readUnshared可以返回可在流中其他地方或通过外部手段获得的类对象或枚举常量。如果反序列化对象定义了readResolve方法,并且该方法的调用返回一个数组,则readUnshared返回该数组的浅克隆;这保证了返回的数组对象是唯一的,并且不能从ObjectInputStream上的readObject或readUnshared调用第二次获得,即使底层数据流已被操作

覆盖此方法的ObjectInputStream子类只能在具有“enableSubclassImplementation”SerializablePermission的安全上下文中构造;在没有此权限的情况下实例化此类子类的任何尝试都将导致抛出SecurityException


但是我想知道是否有人在使用
.readUnshared()
.readObject()

时有过这种用法的实际应用,我相信这可能是与安全相关的非常特殊的情况(?)。像这个(来自)

A.6保护非共享反序列化对象

如果类有任何私有或包私有对象引用字段, 类依赖于这样一个事实,即这些对象引用不是 在类(或包)外部可用,然后 对象必须作为反序列化的一部分进行防御性复制 进程,或者ObjectOutputStream.writeUnshared和 ObjectInputStream.readUnshared方法(在的1.4版中引入) 应使用JavaTM 2 SDK(标准版)来确保 对内部对象的引用

在复制方法中,从流中反序列化的子对象 应被视为“不受信任的输入”:新创建的对象, 初始化为与反序列化的子对象具有相同的值, 应使用readObject方法替换子对象。 例如,假设一个对象有一个私有字节数组字段b 必须保持隐私:

 private void readObject(ObjectInputStream s)
    throws IOException, ClassNotFoundException
{
    s.defaultReadObject();

    b = (byte[])b.clone();

    if (<invariants are not satisfied>)
        throw new java.io.StreamCorruptedException();
}
private void readObject(objectInputStreams)
抛出IOException,ClassNotFoundException
{
s、 defaultReadObject();
b=(字节[])b.clone();
如果()
抛出新的java.io.StreamCorruptedException();
}
在考虑序列化时,此问题尤其重要 包含对的内部(必须是私有)引用的不可变对象 可变子对象。如果未采取特殊措施复制子对象 在反序列化容器对象的过程中,恶意方 对序列化流的写访问可能会违反容器对象的 通过伪造对其可变子对象的引用并使用这些 用于更改容器对象的内部状态的引用。因此, 在这种情况下,不可变容器类必须提供 类特定的反序列化方法,该方法生成 它反序列化的每个可变组件对象。请注意,对于 为了保持不变性,不需要复制 不可变的组件对象

同样重要的是要注意,调用克隆可能并不总是最合适的 防御性复制子对象的正确方法。如果克隆方法无法 被指望制作一份独立的拷贝(而不是“窃取”一份拷贝) 参考副本),应使用替代方法制作 复印件。如果 子对象的类不是final,因为克隆方法或帮助器 它调用的方法可能被子类重写

从JavaTM 2 SDK的1.4版开始,标准版,unique 还可以通过使用 ObjectOutputStream.writeUnshared和ObjectInputStream.readUnshared 方法,从而避免了复杂性、性能成本和内存 防御复制的开销


从来没用过。一种用途是作为协议健全性检查,以确保发送方使用的是
writeUnshared()。
如果发送方未使用,则会导致所述异常。