FindBugs 提出了一个名为 EI_EXPOSE_REP 的错误,其描述如下:
EI:可以通过返回对可变对象的引用来公开内部表示
返回对存储在对象字段之一中的可变对象值的引用会公开该对象的内部表示形式。如果实例由不受信任的代码访问,并且对可变对象进行未经检查的更改会危及安全性或其他重要属性,则您将需要执行不同的操作。在许多情况下,返回对象的新副本是更好的方法。
class Person {
private String[] hobbies;
String[] getHobbies(){ return hobbies;}
void setHobbies(String[] hobbies){ this.hobbies = hobbies;}
}
我知道一些解决办法:
- getHobbies(){返回hobbies.clone();}
- 使用列表代替数组;
我想知道的是为什么只有数组会引发这个错误,列表没有这个问题?为什么数组与其他集合有如此不同?
Findbugs(现已被 Spotbugs 取代)引发了安全问题。这不是一个错误,因为它本身不会产生不需要的行为。但是这种内部数据的暴露可能会在调用者方法中产生错误。
您猜对了,有两种方法可以保护您的 getter 免受暴露:
- 返回数组的副本
Arrays.copyOf(..)
- 将其转换为“不可变”列表
Collections.unmodifiableList(..)
(您也可以使用List.of(..)
从 Java 9 开始)
A List
除非不可修改,否则会发出类似的警告。
这是一个很好的使用习惯Collections
代替Arrays
除非你确实有充分的理由不这样做。
在某些情况下,当您的写入次数很少而读取次数较多时,该类CopyOnWriteArrayList
是一个简单的不可变列表 getter 的绝佳替代方案。
我想知道为什么只是数组会引发这个错误。
这只是一个警告。 Findbugs 在报告旁边显示严重性级别。
对于安全性而言,暴露程度为中等,但对于错误而言,暴露程度较低。
列表就没有这个问题吗?
确实如此。 ArrayList 只是一个带有附加抽象层的数组。
为什么数组与其他集合如此不同?
数组是本机类型,而集合则不是。
行为类似,但您对数组的控制比对集合的控制要少。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)