【问题标题】:FindBugs warning on ThreadLocal initThreadLocal init 上的 FindBugs 警告
【发布时间】:2015-09-04 16:08:25
【问题描述】:

我有 ThreadLocal 实例,它是用重写的 initValue 方法初始化的。我还用@edu.umd.cs.findbugs.annotations.SuppressWarnings("SIC_INNER_SHOULD_BE_STATIC_ANON")注释如下。

@edu.umd.cs.findbugs.annotations.SuppressWarnings("SIC_INNER_SHOULD_BE_STATIC_ANON")
private ThreadLocal<Integer> dbSwitchCount=new ThreadLocal<Integer>() {
    @Override 
    protected Integer initialValue() {
        return 0;
    }
};

Still Sonar 报告抱怨“性能 - 可以重构为命名的静态内部类”。 我怎样才能确保上述抱怨被忽略或者我可以避免这种抱怨的最佳方法。

【问题讨论】:

  • 您使用的是哪个版本的 Java?如果您使用的是 Java 8,我会使用 new ThreadLocal&lt;Integer&gt;().withInitial(() -&gt; 0);
  • 不幸的是我被困在 Java 6 中

标签: java findbugs thread-local


【解决方案1】:

按照 Sonar 的建议“可以重构为命名的静态内部类”。

命名静态内部类:

class MyClass {
    static class MyThreadLocal extends ThreadLocal<Integer> {
        @Override 
        protected Integer initialValue() {
            return 0;
        }
    }
    private ThreadLocal<Integer> dbSwitchCount = new MyThreadLocal();
}

我认为 Sonar 认为这是“性能”改进的原因是因为匿名类是非静态的,将其设为静态可以改进内存管理。

【讨论】:

  • 这应该可以。但我想知道为什么没有应用 SuppressWarnings?
【解决方案2】:

注释不起作用,因为您正在注释dbSwitchCount 字段,而不是匿名类并且错误报告未绑定到该字段。下面是错误报告在 XML 中的样子:

<BugInstance type="SIC_INNER_SHOULD_BE_STATIC_ANON" priority="3" rank="20" abbrev="SIC" 
             category="PERFORMANCE" first="1">
  <Class classname="MyClass$1">
    <SourceLine classname="MyClass$1" start="1" end="10" 
                sourcefile="MyClass.java" sourcepath="MyClass.java"/>
  </Class>
  <SourceLine classname="MyClass$1" start="7" end="7" startBytecode="0" endBytecode="0" 
              sourcefile="MyClass.java" sourcepath="MyClass.java"/>
</BugInstance>

看,dbSwitchCount 字段什么都没有。因此,当抑制过滤器工作时,它不知道 dbSwitchCount 注释与此错误报告有某种联系。不幸的是,我看不到任何方法来注释匿名类本身。唯一可以在不更改实际代码的情况下抑制此警告的方法是注释外部类:

@SuppressFBWarnings("SIC_INNER_SHOULD_BE_STATIC_ANON")
public class MyClass {

    private final ThreadLocal<Integer> dbSwitchCount=new ThreadLocal<Integer>() {
        @Override 
        protected Integer initialValue() {
            return 0;
        }
    };
}

这样警告就会消失(顺便说一句,建议改用@SuppressFBWarnings 注释)。

一般来说,实例绑定(非静态)线程本地是可疑的。例如,参见this question。因此,最初的问题可能是 dbSwitchCount 应该被声明为静态(这样SIC_INNER_SHOULD_BE_STATIC_ANON 警告也会消失)。

更新我检查了这个检测器的 FindBugs 代码。看起来可以添加缺少的错误注释,从而可以抑制注释字段或封闭方法的警告。我在我们的错误跟踪器中创建了一个ticket

UPDATE-2 Fixed in FindBugs trunk.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多