发布
社区首页 >问答首页 >findbugs反对匿名内部类。

findbugs反对匿名内部类。
EN

Stack Overflow用户
提问于 2014-02-24 18:48:01
回答 4查看 19.9K关注 0票数 11

此代码:

代码语言:javascript
代码运行次数:0
复制
Set<Map.Entry<String, SSGSession>> theSet =  new TreeSet<Map.Entry<String, SSGSession>>(new Comparator<Map.Entry<String, SSGSession>>() {

        @Override
        public int compare(final Map.Entry<String, SSGSession> e1, final Map.Entry<String, SSGSession> e2) {
            return e2.getValue().getStartTime().compareTo(e1.getValue().getStartTime());
        }
    }));

触发Sonar中的违规行为,触发具有以下描述的findbug规则"SIC_INNER_SHOULD_BE_STATIC_ANON“:

这个类是一个内部类,但不使用它对创建它的对象的嵌入引用。此引用使类的实例更大,并可能使对创建者对象的引用比必要的时间更长。如果可能的话,这个类应该变成一个静态的内部类。由于匿名内部类不能被标记为静态的,为此需要对内部类进行重构,使其成为一个命名的内部类。

真的?这不是很挑剔吗?我真的应该在匿名内部类中重构一行方法以节省额外引用的成本吗?在这种情况下,它不可能将引用保存得超过必要的时间。

我不介意这样做,因为我们严格执行的编码标准是“零声纳违反”,但我强烈想在这里提出//NOSONAR的理由,因为imho将一行方法提取到静态内部会使代码更难理解。

java纯粹主义者是怎么想的?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-02-24 19:22:57

将评论转化为回答,首先,我可以相信,把它作为匿名的内部类是有道理的,即使这有一个明确的技术理由来挑剔。

尽管如此,我还是要说:遵循您设置的规则。规则创建一致性,当所有代码都以相同的方式编写时,代码库作为一个整体更容易理解。如果某些规则是坏的,在任何地方都禁用它。

当有例外的时候,也需要解释为什么会有例外:对阅读代码的人来说是额外的精神负担,在代码评审中需要讨论的额外项目等等。只有在个别情况下,如果你认为这是一种例外情况,才需要禁用规则。

此外,我也不确定将它作为静态类来执行会更难理解,即使它添加了更多的样板(如果下面不是100%正确的代码,那么我的Java就有点生疏了,尽管可以建议编辑):

代码语言:javascript
代码运行次数:0
复制
Set<Map.Entry<String, SSGSession>> theSet 
    = new TreeSet<Map.Entry<String, SSGSession>>(new SSGSessionStartTimeComparator());

然后在文件中的其他地方,连同其他静态类:

代码语言:javascript
代码运行次数:0
复制
static class SSGSessionStartTimeComparator extends Comparator<Map.Entry<String, SSGSession>>() {
    @Override
    public int compare(final Map.Entry<String, SSGSession> e1, final Map.Entry<String, SSGSession> e2) {
        return e2.getValue().getStartTime().compareTo(e1.getValue().getStartTime());
    }
}
票数 11
EN

Stack Overflow用户

发布于 2014-02-25 09:54:42

为了完整起见,我想在已经提供的优秀答案的基础上添加另一个变体。为Comparator定义一个常量,并使用它:

代码语言:javascript
代码运行次数:0
复制
private static final Comparator<Map.Entry<String, SSGSession>> BY_STARTTIME =
        new Comparator<Map.Entry<String, SSGSession>>() {
    @Override
    public int compare(final Map.Entry<String, SSGSession> e1,
            final Map.Entry<String, SSGSession> e2) {
        return e2.getValue().getStartTime().compareTo(e1.getValue().getStartTime());
    }
};

private void foo() {
    Set<Map.Entry<String, SSGSession>> theSet =
        new TreeSet<Map.Entry<String, SSGSession>>(BY_STARTTIME);
}

这将节省额外的类,就像在hyde's answer中一样。否则,hyde的答案会更好,因为它允许您声明Comparator是可序列化的(因为它没有状态)。如果Comparator不可序列化,您的TreeSet也不能序列化。

票数 4
EN

Stack Overflow用户

发布于 2014-02-25 04:12:39

这里有三种解决方案,其中最好的方法是您无法控制的:

  • 扩展Java语法: ..。theSet =新的静态比较器。
  • 如所述,声明和使用静态类。
  • 忽略此实例中的警告: @SuppressFBWarnings("SIC_INNER_SHOULD_BE_STATIC_ANON") ...你的方法..。

我更喜欢第一种,但这是一段很长的时间。因此,在忽略整个规则项目之前,我会选择最后一个。选择一条规则需要一点痛苦才能推翻它;否则,它只是一种约定或建议。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21996330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档