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

问题: I have a list which is a private member in my class. I have used getter and setter to get and set the values. SOnar throws an error - Mutable members should not be stored o...

问题:

I have a list which is a private member in my class. I have used getter and setter to get and set the values. SOnar throws an error - Mutable members should not be stored or returned directly.

For example: ABC and DEF are two classes.

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

After lot of googling and searching, I have understood that the getter can be changed as follows:

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

When i try to use setter similarly,

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

then the variable starts showing

'private field 'defList' is never assigned.

May I know the correct way to do when it is a list, (a list of another class)


回答1:

The warning is because you did not give the field an initial value. This is how you should implement the code to ensure immutability using 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);
    }

回答2:

I believe it is better not to add additional restrictions (immutability) to the List returned from the getter. If you do that, clients using your List will not be able sort it for example.

So, my recommended approach is this:

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

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

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

From design perspective, an even better API for ABC class would be:

public List<DEF> getDefList()
public void clearDefList()
public void addAllDefs(List<DEF> defs) // Or method name appendDefs
  • 发表于 2019-01-10 01:03
  • 阅读 ( 1223 )
  • 分类:网络文章

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除