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

Java 8调用RuntimeTypeAdapterFactory.of报标签不唯一错误如何解决

问题根因

你遇到的java.lang.IllegalArgumentException: types and labels must be unique报错和Java 8不支持List.of无关,该报错是RuntimeTypeAdapterFactory的内置校验逻辑触发:要求注册的所有子类型Class、对应的type字段标签值必须全局唯一,不可重复。
你感知到报错出现在RuntimeTypeAdapterFactory.of行属于行号对齐偏差,实际报错触发点是后续循环调用factory.registerSubtype的步骤,堆栈日志也明确指向registerSubtype方法。
常见触发场景:

  • Stix2Type.TYPES枚举中存在重复的implementation类,或者重复的toJsonString()返回值
  • 你多次调用了commonGsonBuilder方法,由于Stix2Type是枚举单例,首次调用时已经通过setImplementation设置过实现类、注册过子类型,第二次调用时重复注册触发校验

解决方案

方案1:添加重复校验+单次初始化逻辑

调整代码避免重复注册,同时提前做去重处理:

// 增加全局标记,避免重复初始化枚举实现类
private static volatile boolean stixTypeInitialized = false;

public static GsonBuilder commonGsonBuilder(Map<Stix2Type, Class<? extends TypedStixObject>> customImplementations) {
    RuntimeTypeAdapterFactory<TypedStixObject> factory = RuntimeTypeAdapterFactory.of(TypedStixObject.class, "type", true);
    
    // 只在首次调用时设置枚举实现类,避免重复修改
    if (!stixTypeInitialized) {
        synchronized (Stix2Gson.class) {
            if (!stixTypeInitialized) {
                for (Stix2Type stix2Type : customImplementations.keySet()) {
                    stix2Type.setImplementation(customImplementations.get(stix2Type));
                }
                stixTypeInitialized = true;
            }
        }
    }

    // 注册前先去重,避免重复的类或者标签
    Map<Class<?>, String> classToLabel = new HashMap<>();
    Map<String, Class<?>> labelToClass = new HashMap<>();
    for (Stix2Type value : Stix2Type.TYPES) {
        Class<?> implClazz = value.getImplementation();
        String label = value.toJsonString();
        // 跳过重复的注册项
        if (classToLabel.containsKey(implClazz) || labelToClass.containsKey(label)) {
            continue;
        }
        classToLabel.put(implClazz, label);
        labelToClass.put(label, implClazz);
        factory.registerSubtype(implClazz, label);
    }

    return new GsonBuilder()
        .disableHtmlEscaping()
        .registerTypeHierarchyAdapter(Collection.class, new EmptyCollectionNonSerializer())
        .registerTypeHierarchyAdapter(Stix2Type.class, new Stix2TypeSerializer())
        .registerTypeHierarchyAdapter(Stix2Type.class, new Stix2TypeDeserializer())
        .registerTypeAdapterFactory(factory);
}

方案2:兼容Java 8的RuntimeTypeAdapterFactory替换

如果你使用的eu.csaware.stix2.common.RuntimeTypeAdapterFactory内部实现用到了Java 9+的List.of语法,可以直接替换为Gson官方兼容Java 8的RuntimeTypeAdapterFactory实现,将官方开源的对应类代码复制到你的项目同路径下覆盖原有类即可,官方实现没有使用高版本Java语法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:36:04