2013-01-07 55 views
2

我開始在現有項目中使用findbugs @Nonnull@CheckForNull註釋來防止NPE,並認爲它工作得很好。 我使用@Nonnull作爲返回類型和參數的默認值,並且僅通過添加默認值就可以找到幾個NPE。現在我發現了一個類似於此的方法:如何使用findbugs @Nonnull與外部庫?

@Nonnull 
private Integer getInteger(String key) { 
    return Map.get(key); 
} 

而且它不會產生警告。我明白爲什麼會出現這種情況,但我怎樣才能解決這個問題?你如何在你的項目中解決這個問題?

可以全球應用的解決方案將是優選的,例如,像@ApplyCheckForNullToAllExternalCalls

回答

1

通過將註釋添加到軟件包的package-info.java文件中,您可以將@CheckForNull應用於軟件包內的所有方法返回值(和/或參數),但您無法控制單個方法。

首先,在項目的實用程序包中創建@ReturnValuesAreCheckForNullByDefault

@Documented 
@CheckForNull 
@TypeQualifierDefault(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface ReturnValuesAreCheckForNullByDefault { /* noop */ } 

接下來,創建src/java/util/package-info.java

@ReturnValuesAreCheckForNullByDefault 
package java.util; 

import my.project.util.ReturnValuesAreCheckForNullByDefault; 

最後,享受您的FindBugs警告。

@Nonnull 
public String getValue() { 
    Map<String, String> values = new HashMap<>(); 
    return values.get("foo"); // <-- Possible null pointer dereference ... 
} 

有這樣做的問題是,有在java.*軟件包合同返回null許多方法。使用這些而不檢查null將引發警告。例如,這個NPE安全的代碼還提出了一個警告:

@Nonnull 
public Set<String> getNotNull() { 
    Map<String, String> values = new HashMap<>(); 
    return values.keySet(); 
} 

可以抑制警告與@SuppressFBWarnings,但是這可能會弄亂代碼太多自己的喜好。

+0

Findbugs如何知道'@ ReturnValuesAreCheckForNullByDefault'?我的意思是,FB如何知道如何解釋您的自定義註釋? –

+0

['TypeQualifierDefault'](http://jsr-305.googlecode.com/svn/trunk/javadoc/javax/annotation/meta/TypeQualifierDefault.html)是JSR-305的一部分,並導致其他註釋被結轉添加到附加註釋的元素(方法,參數,字段等取決於其參數)。有關JSR-305的示例,請參閱['ParametersAreNonnullByDefault'](http://jsr-305.googlecode.com/svn/trunk/javadoc/javax/annotation/ParametersAreNonnullByDefault.html),幾乎與上述內容相同。 –

+0

謝謝,我知道package-info.java,但沒有想到爲我的控制之外的軟件包編寫一個。然而,我認爲你是對的,不能使某些Util方法@Nonnull會很煩人。 –