声纳违规:安全 – 数组直接存储

有一个声纳违规:

声纳违规:安全 – 数组直接存储

public void setMyArray(String[] myArray) { this.myArray = myArray; } 

解:

 public void setMyArray(String[] newMyArray) { if(newMyArray == null) { this.myArray = new String[0]; } else { this.myArray = Arrays.copyOf(newMyArray, newMyArray.length); } } 

但是我想知道为什么?

这是抱怨你正在存储的数组是由调用者保持相同的数组。 也就是说,如果调用者随后修改这个数组,则存储在该对象中的数组(也就是对象本身)将会改变。

解决scheme是在对象传递时创build一个副本。 这就是所谓的防御性复制 。 集合的后续修改不会影响存储在对象中的数组。

返回一个集合(例如,在相应的getMyArray()调用中)通常也是这样做的。 否则,接收方可以执行修改并影响存储的实例。

请注意,这显然适用于所有可变集合(实际上所有可变对象) – 不仅仅是数组。 还要注意,这具有性能影响,需要与其他问题一起评估。

这就是所谓的防御性复制。 关于这个话题的一篇不错的文章是“无论如何,谁的对象? 由Brian Goetz撰写,其中讨论了getter和setter的值和引用语义之间的区别。

基本上,引用语义(没有副本)的风险是你错误地认为你拥有这个数组,而当你修改它时,你也修改了其他具有数组别名的结构。 您可以在网上find许多关于防御性复制和与对象别名有关的问题的信息。

我遇到过同样的问题:

安全性 – 数组直接存储用户提供的数组 “palomitas”直接存储。

我原来的方法:

 public void setCheck(boolean[] palomitas) { this.check=palomitas; } 

固定转向:

 public void setCheck(boolean[] palomitas) { if(palomitas == null) { this.check = new boolean[0]; } else { this.check = Arrays.copyOf(palomitas, palomitas.length); } } 

其他例子:

安全性 – 数组直接存储在用户提供的数组中

 private String[] arrString; public ListaJorgeAdapter(String[] stringArg) { arrString = stringArg; } 

固定:

 public ListaJorgeAdapter(String[] stringArg) { if(stringArg == null) { this.arrString = new String[0]; } else { this.arrString = Arrays.copyOf(stringArg, stringArg.length); } } 

为了消除它们,你必须在存储/返回它之前克隆数组,如下面的类实现所示,所以没有人可以修改或获取你的类的原始数据,但只有它们的副本。

 public byte[] getarrString() { return arrString.clone(); } /** * @param arrStringthe arrString to set */ public void arrString(byte[] arrString) { this.arrString= arrString.clone(); } 

我用它这样,现在我没有得到任何声纳侵犯…

这比所有这一切更容易。 您只需要将方法参数重命名为其他任何内容即可避免声纳违规。

http://osdir.com/ml/java-sonar-general/2012-01/msg00223.html

 public void setInventoryClassId(String[] newInventoryClassId) { if(newInventoryClassId == null) { this.inventoryClassId = new String[0]; } else { this.inventoryClassId = Arrays.copyOf(newInventoryClassId, newInventoryClassId.length); } } 

走防守实施路可以节省你很多时间。 在番石榴你得到另一个很好的解决scheme,以达到目标:ImmutableCollections

http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained

在某些情况下,这是一个devise决定,不会错过。 在这些情况下,您需要修改Sonar规则以排除它,以便在报告中不显示此类问题。