You need to enable JavaScript to run this app. Java中如何为无共同接口两类提取switch重复通用函数
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何为无共同接口两类提取switch重复通用函数

泛型化实现通用非空校验逻辑

问题根源

IntelliJ 自动提取代码段的默认逻辑是基于当前上下文的具体类型做硬编码,提取时只会识别当前选中代码的Form类型,把签名写死为Function<Form, Form>,没有自动推导抽象为泛型,自然无法兼容Note类型。
而你这段重复逻辑本身的能力边界非常清晰:

  • 接收任意类型的入参
  • 判断入参是否为null,是则抛出指定异常
  • 校验通过则原样返回入参,全程不需要访问入参的任何方法、字段
    这种逻辑根本不依赖两个类的共同接口,只需要把签名改成支持任意泛型T,就能做到类型安全的通用兼容。

重构实现

第一步:定义泛型通用校验函数

直接利用Java泛型的类型推断能力,把硬编码的Form替换为任意泛型T:

/**
 * 通用非空校验:对象为null则抛出指定异常,否则原样返回
 * @param exceptionSupplier 空值时抛出的异常的获取方法
 * @param <T> 任意入参、出参类型,类型保持一致
 */
private static <T> Function<T, T> requireNonNullOrThrow(Supplier<RuntimeException> exceptionSupplier) {
    return obj -> {
        if (obj == null) {
            throw exceptionSupplier.get();
        }
        return obj;
    };
}

第二步:替换原有重复逻辑

替换后switch分支的代码会大幅简化,且完全保留原有业务逻辑:

case "form" -> handleProvider.withHandle(handle -> handle.attach(FormDao.class).findFormById(id))
        // 编译器会自动推断T为Form类型
        .thenApply(requireNonNullOrThrow(() -> exceptionIfNotFound))
        .thenApply(obj -> obj.exportedDocument);

case "note" -> handleProvider.withHandle(handle -> handle.attach(NoteDao.class).findNoteById(id))
        // 编译器会自动推断T为Note类型
        .thenApply(requireNonNullOrThrow(() -> exceptionIfNotFound));

方案优势

  • 不需要Form、Note类实现任何共同接口,因为校验逻辑全程不感知T的具体类型
  • Java编译器会在thenApply的调用点,根据上游CompletableFuture的返回类型自动推导T的具体值,不需要手动写泛型参数
  • 没有类型擦除带来的unchecked警告,全程类型安全
  • 后续新增其他业务对象的分支时,直接复用这个校验函数即可,不需要重复写判空逻辑

注:如果你的exceptionIfNotFound是提前定义好的异常Supplier,不需要每次传参,也可以把函数定义为类级别的静态常量,但注意这种写法会因为类型擦除带来少量编译警告,优先用上面的泛型方法写法最稳妥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.30 16:27:04