Sonar - 存储副本 - 不应直接存储或返回可变成员

Sonar - Store a copy - Mutable members should not be stored or returned directly

我有一个列表,它是我 class 中的私有成员。 我使用 getter 和 setter 来获取和设置值。 SONar 抛出错误 - 不应直接存储或返回可变成员。

例如:ABC和DEF是两个class。

class ABC{
private List<DEF> defList;
public List<DEF> getDefList() { return defList; }
public void setDefList(List<DEF> defList) { this.defList = defList; }

经过大量谷歌搜索和搜索,我了解到 getter 可以更改如下:

public List<DEF> getDefList() { return new ArrayList<>(defList); }

当我尝试类似地使用 setter 时,

public void setDefList(List<DEF> defList) { this.defList.addAll(defList); }

然后变量开始显示

'private field 'defList' is never assigned.

请问当它是一个列表时,(另一个列表class)的正确做法

注意:Prasad Karunagoda 和 Leo Aso 的答案都有效。我不能将两者都标记为已接受的答案。所以在这里记下

这个警告是因为你没有给这个字段一个初始值。这就是您应该如何使用 java.util.Collections.

实现代码以确保不变性
class ABC {
    private List<DEF> defList = Collections.emptyList();

    public List<DEF> getDefList() { 
        return defList;
    }

    public void setDefList(List<DEF> defList) {
        // defensively copy, then make immutable
        defList = new ArrayList<>(defList);
        this.defList = Collections.unmodifiableList(defList);
    }

我认为最好不要对从 getter 返回的 List 添加额外的限制(不变性)。例如,如果您这样做,使用您的 List 的客户将无法对其进行排序。

所以,我推荐的方法是:

public class ABC {
  private List<DEF> defList = new ArrayList<>();

  public List<DEF> getDefList() {
    return new ArrayList<>(defList);
  }

  public void setDefList(List<DEF> defList) {
    if (defList == null)
        throw new IllegalArgumentException("Parameter defList is null");
    this.defList.clear();
    this.defList.addAll(defList);
  }
}

从设计的角度来看,ABC class 更好的 API 应该是:

public List<DEF> getDefList()
public void clearDefList()
public void addAllDefs(List<DEF> defs) // Or method name appendDefs