声纳-存储副本-可变成员不应直接存储或退回

时间:2019-01-08 12:28:36

标签: java arraylist sonarqube mutable

我有一个清单,该清单是班上的私人成员。 我已经使用getter和setter来获取和设置值。 SOnar引发错误-可变成员不应直接存储或返回。

例如:ABC和DEF是两个类。

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

当我尝试类似地使用二传手时,

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

然后变量开始显示

'private field 'defList' is never assigned.

当列表(另一个类的列表)时,我是否可以知道正确的方法

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

2 个答案:

答案 0 :(得分:0)

警告是因为您没有为该字段提供初始值。这是应该使用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);
    }

答案 1 :(得分:0)

我相信最好不要对从吸气剂返回的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类的一个更好的API是:

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