javaintellij-ideaconstructorwarnings

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


I have this block of code:

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;
    }
}

For my constructor which passes a LinearFunction as a parameter, it says

Copy constructor does not copy field 'xIntercept'

Which I don't understand, because xIntercept is getting initialized in the other constructor


Solution

  • IntelliJ is complaining that you don't copy the value from one LinearFunction instance to the other. It's analysis is apparently not thorough enough to understand that this member is computed directly from the two other members, and can never change afterward (because it's final).

    You could copy it directly to appease IntelliJ, but personally, I'd just suppress this warning - warnings and static analysis are supposed to help you write better, bug free, code, not to control your work.

    EDIT:
    Adding some more details, as per the comments below:

    First, if you want to appease IntelliJ, you need to make sure your copy constructor copies all the fields. To do this, I'd refactor out a (private) constructor that takes values for the three fields, and have the other two constructors call it:

    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;
    }
    

    However, I think the preferred method would be to just suppress this warning by adding the appropriate @SuppressWarnings annotation:

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

    If you aren't sure what annotation to to use, IntelliJ can help you here (note: I'm using Ultimate Edition, but I'm 99% sure it's the same in the community edition) - place your caret on the constructor's name with the warning and hit Alt+Enter. This will open a context menu with all the warnings on that constructor. Select the relevant one ("Inspection 'Copy constructor misses fields' options"), and hit the right arrow key to get another context menu where you can choose how to deal with it (e.g., suppress the warning for that specific constructor, for the entire class, edit the IDE settings to disable this warning, etc.):

    enter image description here