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

如何用方法引用替代Lambda满足SonarQube规则squid:S1612?

解决SonarQube规则squid:S1612的方法引用问题,同时保证每次生成新实例

你遇到的这个问题很典型——直接用new Person()::id确实会踩坑,因为这个写法本质是先创建一个固定的Person实例,然后引用它的id方法,所以每次调用apply时都是在同一个实例上修改并返回,自然所有调用结果都是同一个对象,导致测试失败。

正确的解决方案:新增静态工厂方法(推荐)

最清晰且符合规则的方式是在Person类中新增一个静态工厂方法,把Lambda里的逻辑封装进去,然后直接引用这个静态方法:

public class Person {
    Integer id;
    String name;

    // 原有方法...
    public Person id(Integer id) {
        setId(id);
        return this;
    }
    public Person name(String name) {
        setName(name);
        return this;
    }
    /* 构造方法、getter、setter等... */

    // 新增静态工厂方法
    public static Person createWithId(Integer id) {
        return new Person().id(id);
    }
}

然后在Simplifiers类中修改PERSON_1的定义:

public class Simplifiers {
    // 现在符合squid:S1612规则,且每次调用都会生成新实例
    public static final Simplifier<Person> PERSON_1 = new Simplifier<>(Person::createWithId);

    public static final Simplifier<Person> PERSON_2 = new Simplifier<>(
        id -> {
            final Person action2 = new Person();
            return action2.id(id);
        });
}

这样修改后,每次调用PERSON_1.simplify(id)都会调用Person.createWithId,而这个方法每次都会创建新的Person实例并设置id,完全满足测试要求,同时SonarQube的规则检查也会通过。

为什么new Person()::id不行?

再拆解一下这个写法的本质:

  • new Person()会立即创建一个Person实例,这个实例是固定的
  • ::id引用的是这个固定实例的id方法,方法签名是Person id(Integer id)
  • 当把这个方法引用作为Function<Integer, Person>传递给Simplifier时,每次调用apply(id)都是在同一个实例上执行id(id),然后返回这个实例,所以所有调用返回的都是同一个对象,这就是测试失败的原因。

另一种不新增方法的写法(不推荐,可读性差)

如果不想新增静态方法,其实很难绕开Lambda实现纯方法引用(因为需要动态接收id参数并创建新实例),强行组合的写法可读性极差,比如:

// 这种写法看似用了方法引用,但本质还是嵌套Lambda,不符合规则要求
public static final Simplifier<Person> PERSON_1 = new Simplifier<>(
    id -> ((Supplier<Person>) Person::new).get().id(id)
);

所以这种方式完全没必要,还是新增静态工厂方法更靠谱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:31:07