2015-09-04 3 views
2

У меня есть экземпляр ThreadLocal, который был инициализирован с переопределенным initValue способом. Также я аннотировал его с @edu.umd.cs.findbugs.annotations.SuppressWarnings("SIC_INNER_SHOULD_BE_STATIC_ANON") следующим образом.FindBugs warning on ThreadLocal init

@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; 
    } 
}; 

Еще Sonar отчета жалуется «Производительность - Может быть повторно вынесен в имени статического внутреннего класса». Как я могу удостовериться, что вышеуказанные жалобы игнорируются или каким лучшим способом я могу избежать жалобы.

+0

Какую версию Java вы используете? Если вы используете Java 8, я бы просто использовал 'new ThreadLocal () .withInitial (() -> 0);' –

+0

К сожалению, я застрял на Java 6 – Brinal

ответ

2

Выполняет то, что предлагает Сонар «Может быть реорганизован в именованный статический внутренний класс».

Названный статический внутренний класс:

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

Я думаю, что причина Sonar думает, что это «Performance» улучшение происходит потому, что анонимный класс не является статическим, и делает его статичным улучшает управление памятью.

+0

Это должно сработать. Но мне интересно, почему SuppressWarnings не применяется? – Brinal

1

Аннотации не работают, потому что вы аннотируете поле 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 в нашем трекере ошибок.

ОБНОВЛЕНИЕ-2Fixed in FindBugs trunk.