FindBugs引发了一个由Array引起的名为EI_EXPOSE_REP的错误

时间:2017-11-15 03:25:04

标签: java arrays findbugs

FindBugs引发了一个名为EI_EXPOSE_REP的错误,其中包含以下描述:

EI:可以通过返回对可变对象的引用来公开内部表示

返回对存储在对象的一个​​字段中的可变对象值的引用,公开该对象的内部表示。如果不受信任的代码访问实例,并且对可变对象的未经检查的更改会危及安全性或其他重要属性,则需要执行不同的操作。在许多情况下,返回对象的新副本是一种更好的方法。

class Person {
    private String[] hobbies;
    String[] getHobbies(){ return hobbies;}
    void setHobbies(String[] hobbies){ this.hobbies = hobbies;}
}

我知道一些解决方案:

  1. getHobbies(){return hobbies.clone();}
  2. 使用List而不是Array;
  3. 我想知道的是为什么只是数组引发了这个错误,列表没有这个问题?为什么数组与其他集合如此不同?

2 个答案:

答案 0 :(得分:3)

Findbugs(现在由Spotbugs取代)引发了一个安全问题。它不是一个bug,因为它本身不会产生不需要的行为。但是这种内部数据暴露可能会在调用方法中产生错误。

你猜对了,有两种方法可以保护你的吸气剂免受暴露:

  • 使用Arrays.copyOf(..)
  • 返回数组的副本
  • 使用Collections.unmodifiableList(..)
  • 将其转换为“不可变”列表
除非作出不可修改,否则List会发出类似的警告。 使用Collections代替Arrays是一种很好的做法,除非你有充分的理由不这样做。

在某些情况下,当你的写入很少且读取次数很多时,类CopyOnWriteArrayList是一个很好的替代方法,可以使用简单的不可变列表获取器。

我想知道的是为什么只是数组会引发这个错误。
这只是一个警告。 Findbugs在报告旁边显示严重性级别 曝光是安全性的中等,但对于错误来说是低的。

列表没有此问题?
确实如此。 ArrayList只是一个带有附加抽象层的数组。

为什么数组与其他集合如此不同?
数组是本机类型,而集合则不是。
行为类似,但您对阵列的控制比对集合的控制要少。

答案 1 :(得分:2)

我在POJO类中的byte []变量遇到了这个问题。如果需要,可以使用批注来隐藏它:@SuppressFBWarnings(value = {“ EI_EXPOSE_REP”,“ EI_EXPOSE_REP2”})