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

如何结合Spring与工厂模式避免原始类型警告?

消除工厂模式中的原始类型警告并优化实现

问题根源

你遇到的原始类型警告,本质是泛型接口Builder<T>被当作原始类型使用,未指定具体泛型参数;同时Test类调用process时,传入的Dto对象与Builder期望的泛型类型(如DtoOne)无绑定,既引发警告也存在潜在类型转换风险。

解决方案与优化实现

1. 修正Factory类泛型使用,消除原始类型警告

给Factory中的集合和方法添加合理泛型通配符,替代原始类型:

@Service
public class Factory {
    // 使用Builder<?>代替原始Builder类型
    private final Map<Builder.TYPE, Builder<?>> builderMap;

    // 构造方法使用List<Builder<?>>
    public Factory(List<Builder<?>> builders) {
        this.builderMap = builders.stream()
                .collect(Collectors.toMap(Builder::getType, Function.identity()));
    }

    // 返回Builder<?>而非原始Builder
    public Builder<?> getBuilder(Builder.TYPE type) {
        return builderMap.get(type);
    }
}

2. 增强类型安全,规避强制转换风险

Test类中直接调用process会因泛型不匹配引发警告,通过类型检查+安全转换解决,配合@SuppressWarnings消除合理警告:

@Service
public class Test {
    private final Factory factory;

    public Test(Factory factory) {
        this.factory = factory;
    }

    public void test(Dto testObject) {
        Builder<?> builder = factory.getBuilder(testObject.getType());
        // 先做类型检查,确保当前builder可处理传入对象类型
        if (builder != null) {
            // 标记已知安全的泛型转换,消除警告
            @SuppressWarnings("unchecked")
            Builder<Dto> typedBuilder = (Builder<Dto>) builder;
            typedBuilder.process(testObject);
        } else {
            // 处理不支持的类型场景
            throw new IllegalArgumentException("Unsupported object type: " + testObject.getType());
        }
    }
}

3. 进阶优化:绑定TYPE与DTO类型(可选)

若要进一步强化类型安全,可给TYPE枚举添加泛型,让每个枚举值与对应DTO类型绑定:

public interface Builder<T> {
    // 泛型枚举,绑定对应的DTO类型
    enum TYPE<T> {
        ONE(DtoOne.class);

        private final Class<T> dtoClass;

        TYPE(Class<T> dtoClass) {
            this.dtoClass = dtoClass;
        }

        public Class<T> getDtoClass() {
            return dtoClass;
        }
    }

    TYPE<T> getType();
    ProcessedObject process(T object);
}

修改TestBuilder的getType方法:

@Service
public class TestBuilder implements Builder<DtoOne> {
    @Override
    public TYPE<DtoOne> getType() {
        return TYPE.ONE;
    }

    @Override
    public ProcessedObject process(DtoOne object) {
        // 处理逻辑
        return new ProcessedObject();
    }
}

此时Test类的类型检查可更严谨:

public void test(Dto testObject) {
    Builder<?> builder = factory.getBuilder(testObject.getType());
    Builder.TYPE<?> type = testObject.getType();
    // 校验对象是否属于当前TYPE对应的DTO类
    if (builder != null && type.getDtoClass().isInstance(testObject)) {
        @SuppressWarnings("unchecked")
        Builder<Dto> typedBuilder = (Builder<Dto>) builder;
        typedBuilder.process(testObject);
    } else {
        throw new IllegalArgumentException("Object type mismatch for type: " + type);
    }
}

关键说明

  • 用Builder<?>替代原始类型Builder,既消除警告又保留泛型灵活性;
  • 类型转换前添加实例检查,避免ClassCastException,仅对已知安全的转换使用@SuppressWarnings("unchecked"),不全局禁用警告;
  • 绑定枚举与DTO类型的进阶方案,能在编译期和运行期提供更强类型安全保障,适合复杂业务场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:45:45