You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用Java 9 ObjectInputFilter的references大小约束?

详解Java 9 ObjectInputStream中的references安全约束

嘿,这个问题问到点子上了——Java 9给ObjectInputStream新增的几个反序列化安全限制里,references确实是最容易让人混淆的那个,我来给你拆解明白。

首先得搞清楚:references约束跟踪的对象引用,到底存在哪儿?
ObjectInputStream在反序列化过程中,会维护一个内部对象引用表。这个表的作用是记录已经成功反序列化的对象实例,用来处理对象的重复引用或者循环引用场景——比如反序列化一个对象A,它里面引用了对象B,之后再遇到对B的引用时,就直接从这个表里取出已有的实例,不用重新创建,这样既保证了对象引用的一致性,也避免了重复反序列化的开销。

那references约束到底管什么?
它限制的是这个内部引用表中能容纳的唯一对象的最大数量。一旦反序列化过程中,引用表的大小超过了你设置的阈值,JVM会直接抛出StreamCorruptedException,中断反序列化操作。这个约束主要是用来防范恶意序列化数据的攻击——比如攻击者构造一个包含大量重复/循环引用的序列化流,试图耗尽JVM内存,references就能在问题扩大前直接终止操作。

怎么正确使用references约束?

  • 通过对象输入过滤器配置:你需要用ObjectInputStream.setObjectInputFilter()方法来设置这个阈值,举个实际代码例子:
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("your-data.ser"))) {
    ois.setObjectInputFilter(filterInfo -> {
        // 限制引用表最多容纳1000个唯一对象
        if (filterInfo.references() > 1000) {
            return ObjectInputFilter.Status.REJECTED;
        }
        // 可以同时搭配其他约束,比如数组长度、深度等
        if (filterInfo.arrayLength() > 500) {
            return ObjectInputFilter.Status.REJECTED;
        }
        return ObjectInputFilter.Status.ALLOWED;
    });
    Object deserializedObj = ois.readObject();
} catch (IOException | ClassNotFoundException e) {
    // 处理异常
}
  • 根据业务场景设置合理阈值:如果你的序列化数据都是简单对象(比如单个实体类,没有复杂关联),设置几百的阈值就足够;如果是处理复杂的对象图(比如包含多层关联的业务对象、集合),可以适当调高,但别设得过大——毕竟安全约束的核心是防止资源耗尽,阈值太高就失去了防护意义。
  • 注意计数规则:references统计的是唯一对象的数量,同一个对象被多次引用不会重复计数。比如你反序列化一个List,里面100个元素都引用了同一个User对象,那引用表只会记录这个User一次,references的计数只会加1(加上List本身就是2)。

最后补充一句:你提到“它并非指当前……”,没错,references绝对不是指单个对象的引用数量,而是从反序列化开始到当前时刻,所有被加入引用表的全局唯一对象总数。

内容的提问来源于stack exchange,提问作者Caranown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:00:08