02
Дек
2017

Помогите понять потенциальный bug, навязаный утилитой Findbugs. Мутирующие объекты в set() методе

При написании кода я использую утилиту FindBugs, для поиска потенциальных багов.

Допустип у меня есть класс :

public class Line<T> implements Serializable, Cloneable {

private T[] pointsOnLine;

private T valueMinPoint;
private T valueMaxPoint;

public Line() {
}

public Line(T[] pointsOnLine) {
    this.pointsOnLine = pointsOnLine;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Line)) return false;

    Line<?> line = (Line<?>) o;

    // Probably incorrect - comparing Object[] arrays with Arrays.equals
    if (!Arrays.equals(getPointsOnLine(), line.getPointsOnLine())) return false;
    if (getValueMinPoint() != null ? !getValueMinPoint().equals(line.getValueMinPoint()) : line.getValueMinPoint() != null)
        return false;
    return getValueMaxPoint() != null ? getValueMaxPoint().equals(line.getValueMaxPoint()) : line.getValueMaxPoint() == null;
}

@Override
public int hashCode() {
    int result = Arrays.hashCode(pointsOnLine);
    result = 31 * result + (valueMaxPoint != null ? valueMaxPoint.hashCode() : 0);
    result = 31 * result + (valueMinPoint != null ? valueMinPoint.hashCode() : 0);
    return result;
}

@Override
public String toString() {
    return "Line[" +
            "pointsOnLine=" + Arrays.toString(pointsOnLine) +
            ", valueMaxPoint=" + valueMaxPoint +
            ", valueMinPoint=" + valueMinPoint +
            ']';
}

@Override
protected Line<T> clone() throws CloneNotSupportedException {
    Line<T> line = (Line<T>) super.clone();
    line.setValueMinPoint(this.getValueMinPoint());
    line.setValueMaxPoint(this.getValueMaxPoint());
    line.setPointsOnLine(this.getPointsOnLine());
    return line;
}

public T[] getPointsOnLine() {
    return pointsOnLine;
}

public void setPointsOnLine(T[] pointsOnLine) {
    this.pointsOnLine = pointsOnLine;
}

public T getValueMinPoint() {
    return valueMinPoint;
}

public void setValueMinPoint(T valueMinPoint) {
    this.valueMinPoint = valueMinPoint;
}

public T getValueMaxPoint() {
    return valueMaxPoint;
}

public void setValueMaxPoint(T valueMaxPoint) {
    this.valueMaxPoint = valueMaxPoint;
}

}

Проверку корректности переданного аргумента в setter, я еще не успел добавить.

При проверки кода утилитой, она ругнулась мне на методы setPointsOnLine() и на getPointsOnLine(). А также и на конструктор.

А именно :

EI: May expose internal representation by returning reference to mutable object (EI_EXPOSE_REP)

Returning a reference to a mutable object value stored in one of the object's fields exposes the internal representation of the object. If instances are accessed by untrusted code, and unchecked changes to the mutable object would compromise security or other important properties, you will need to do something different. Returning a new copy of the object is better approach in many situations.

Здесь говорится о том, что объект которому присвается значение объекта переданного аргументом в setter, является mutable и может быть изменен из любого участка кода.

Я понимаю как исправить потенциальный баг, допустим :

public void setPointsOnLine(T[] pointsOnLine) {
    this.pointsOnLine = new Line<>(pointsOnLine).getPointsOnLine();
}

Но я не понимаю, почему это так работает и как же такое код писать в дальнейшем в других классах? Неужели если полем класса является ссылочная переменная, то всегда писать такой код в setter-ах? И что имеется ввиду, что этот объект mutable? Тоесть, если я уберу getter, то объект будет immutable?

Источник: https://ru.stackoverflow.com/questions/752645/%D0%9F%D0%BE%D0%BC%D0%BE%D0%B3%D0%B8%D1%82%D0%B5-%D0%BF%D0%BE%D0%BD%D1%8F%D1%82%D1%8C-%D0%BF%D0%BE%D1%82%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9-bug-%D0%BD%D0%B0%D0%B2%D1%8F%D0%B7%D0%B0%D0%BD%D1%8B%D0%B9-%D1%83%D1%82%D0%B8%D0%BB%D0%B8%D1%82%D0%BE%D0%B9-findbugs-%D0%9C%D1%83%D1%82%D0%B8%D1%80%D1%83%D1%8E%D1%89%D0%B8%D0%B5-%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA

Тебе может это понравится...

Добавить комментарий