【问题标题】:FindBugs raises a bug called EI_EXPOSE_REP caused by ArrayFindBugs 引发了一个由 Array 引起的名为 EI_EXPOSE_REP 的错误
【发布时间】:2018-04-28 04:08:22
【问题描述】:

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. 使用列表代替数组;

我想知道的是为什么只是数组会引发这个错误,而列表没有这个问题?为什么数组与其他集合如此不同?

【问题讨论】:

  • 我不确定为什么您没有收到相同的列表警告,因为列表也是可变的。

标签: java arrays findbugs


【解决方案1】:

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

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

  • 使用Arrays.copyOf(..) 返回数组的副本
  • 使用 Collections.unmodifiableList(..) 将其转换为“不可变”列表(从 Java 9 开始,您也可以使用 List.of(..)

List 将发出类似的警告,除非使其不可修改。 使用Collections 而不是Arrays 是一个很好的做法,除非您真的有充分的理由不这样做。


在某些情况下,当您有少量写入和大量读取时,CopyOnWriteArrayList 类是一个简单的不可变列表 getter 的绝佳替代方案。


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

列表没有这个问题?
确实如此。 ArrayList 只是一个带有额外抽象层的 Array。

为什么数组与其他集合如此不同?
Array 是本机类型,而 Collections 不是。
行为类似,但您对 Array 的控制少于对 Collection 的控制。

【讨论】:

  • 当我将 'private String[] hobbies' 更改为 'private List hobbies' 时确实如此,发现错误不会引发错误并进行测试。我只是不知道为什么。
  • 尝试在选项中增加 Findbugs 的敏感度。也许你没有达到最高级别的警告。
  • 谢谢,你帮了大忙。而且我知道一个新的分析工具来发现错误---Spotbugs。大声笑
【解决方案2】:

我的 POJO 类中的 byte[] 变量出现了这个问题。如果需要,可以使用注释来抑制它:@SuppressFBWarnings(value = {"EI_EXPOSE_REP", "EI_EXPOSE_REP2"})

【讨论】:

    猜你喜欢
    • 2011-07-25
    • 1970-01-01
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多