IntelliJ 显示警报:"Copy constructor does not copy field."

IntelliJ showing alert: "Copy constructor does not copy field."

我有这段代码:

public class LinearFunction implements Function<Double, Double> {
    private final double slope;
    private final double yIntercept;
    private final double xIntercept;
    
    public LinearFunction(double m, double b) {
        this.slope = m;
        this.yIntercept = b;
        this.xIntercept = -yIntercept / slope;
    }


    public LinearFunction(LinearFunction f) {
        this(f.slope, f.yIntercept);
    }
    @Override
    public Double apply(final Double x) {
        return slope * x + yIntercept;
    }
}

对于传递 LinearFunction 作为参数的构造函数,它说

Copy constructor does not copy field 'xIntercept'

我不明白,因为 xIntercept 正在另一个构造函数中初始化

IntelliJ 抱怨您没有将值从一个 LinearFunction 实例复制到另一个实例。它的分析显然不够彻底,无法理解这个成员是直接从其他两个成员计算出来的,并且以后永远不会改变(因为它是final)。

您可以直接复制它以安抚 IntelliJ,但就我个人而言,我只是禁止显示此警告 - 警告和静态分析应该帮助您编写更好、无错误的代码,而不是控制您的工作。

编辑:
根据以下评论添加更多详细信息:

首先,如果你想安抚 IntelliJ,你需要确保你的复制构造函数复制所有字段。为此,我将重构一个(私有)构造函数,它为三个字段取值,并让其他两个构造函数调用它:

public LinearFunction(double m, double b) {
    this(m, b, -m / b);
}

public LinearFunction(LinearFunction f) {
    this(f.slope, f.yIntercept, f.xIntercept);
}

private LinearFunction(double slope, double yIntercept, double xIntercept) {
    this.slope = slope;
    this.yIntercept = yIntercept;
    this.xIntercept = xIntercept;
}

但是,我认为首选方法是通过添加适当的 @SuppressWarnings 注释来抑制此警告:

@SuppressWarnings("CopyConstructorMissesField")
public LinearFunction(LinearFunction f) {
    this(f.slope, f.yIntercept);
}

如果您不确定要使用什么注释,IntelliJ 可以在此处为您提供帮助(注意:我使用的是终极版,但我 99% 确定它在社区版中是相同的)- 将您的在带有警告的构造函数名称上插入符号,然后点击 Alt+Enter。这将打开一个上下文菜单,其中包含有关该构造函数的所有警告。 Select 相关的(“Inspection 'Copy constructor misses fields' options”),然后点击向右箭头键获得另一个上下文菜单,您可以在其中选择如何处理它(例如,抑制该特定构造函数的警告,对于整个 class,编辑 IDE 设置以禁用此警告等):

在这种情况下,您可以忽略警告消息,因为它是“误报”。 如果您希望编译器停止产生警告,请使用 @SuppressWarnings("CopyConstructorMissesField"):

注释该方法
 @SuppressWarnings("CopyConstructorMissesField")
    public LinearFunction(LinearFunction f) {
        this(f.slope, f.yIntercept);
    }