2012-09-14 16 views
33

com.google.common.base.Function接口(從Google Guava)定義apply爲:@Nullable輸入觸發FindBugs的警告

@Nullable T apply(@Nullable F input);

的方法,具有以下的Javadoc註釋:

@throws NullPointerException if {@code input} is null and this function does not accept null arguments

FindBugs的抱怨我的實現功能:

private static final class Example implements Function<MyBean, String> { 
    @Override 
    @Nullable 
    public String apply(@Nullable MyBean input) { 
     if (null == input) { 
      throw new NullPointerException(); 
     } 
     return input.field; 
    } 
} 

高優先級警告:

NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE,優先順序:高度

輸入必須爲非空,但被標記可爲空

該參數始終以非空的方式使用,但該參數明確註釋爲Nullable。參數或註釋的使用是錯誤的。

我的功能不支持null輸入,如果是這種情況,則會引發異常。如果我理解正確,FindBugs將此視爲非空要求。

對我來說,它看起來像一個矛盾:輸入是@Nullable,但方法@throws NullPointerException當它爲null。我錯過了什麼嗎?

擺脫我可以看到的警告的唯一方法是手動抑制。 (顯然,番石榴密碼不在我的控制之下)。

誰對@Nullable註釋,FindBugs,Guava或我自己的用法有錯?

+4

你說你會在簽名中接受null,然後你在* body中拒絕* null值。這聽起來像你誤解了「@ Nullable」的用途。 –

+4

我爲輸入參數添加'@ Nullable'的唯一原因是它是'Function'接口定義的。 無論如何,我從@Xaerxess建議中刪除了參數中的'@ Nullable'註釋,但FindBugs不斷抱怨。 – vitaly

回答

28

你的實現是錯誤的;)

基本上文檔說(我意譯,強調):

@throws NullPointerException如果input爲null,並且具體 函數實現不接受空參數

通過實現你的功能,你必須決定它是否接受空值。在第一種情況:

private static final class Example implements Function<MyBean, String> { 
    @Override 
    @Nullable 
    public String apply(@Nullable MyBean input) { 
     return input == null ? null : input.field; 
    } 
} 

在第二種情況:

​​

在兩個例子中返回null是允許的。

編輯:那番石榴的所有包使用@javax.annotation.ParametersAreNonnullByDefault,因此,如果@Nullable存在就意味着「暫停全球@Nonnull和允許空值在這裏」,如果不是它的意思是「禁止在這裏空」

注意。也就是說,你可能希望在你的參數中使用@Nonnull註釋或者在包中使用@ParametersAreNonnullByDefault來告訴FindBugs函數的參數不能爲空。

編輯2:

原來this case is known issue,見註釋#3(番石榴的領先開發凱文Bourrillion,他與比爾·普格,FindBugs的鉛對話):

我的提法是與比爾·普格進行一系列面對面的對話。 他斷言@Nullable意味着只有一些亞型 可能接受空。這似乎是由findbugs爲我們所承認的 - 我們的代碼非常乾淨地通過了可空性檢查(儘管我們 應該再次檢查,因爲這個特定的功能更改)。

+0

這讓我想知道是否可以刪除實現中的接口指定的註釋? – vitaly

+1

您不會將它們從界面中刪除,而是將其添加到您的實現中。如果'Function'允許你使用null作爲參數,這並不意味着你必須在你的impl中允許null,就像'Function'合同一樣。 – Xaerxess

+4

註解已經由框架接口指定,我不能(也不打算)如果從那裏刪除。 我可以編輯的唯一代碼是我自己的代碼(=實現)。 我從我的實現中刪除了@Nullable註釋,但FindBugs不斷抱怨。 – vitaly

3

標記參數@Nonnull解決findbugs的問題。

0

它似乎默認谷歌Guava函數默認情況下是@Nullable - 當沒有註釋時,我收到Findbugs錯誤,指出「result必須是nonnull但被標記爲空」。在函數聲明中添加@Nonnull有以下幫助:

new Function<Object, Object>() { 
      @Nonnull 
      public Object apply(@Nonnull Object object) { 

現在Findbugs很高興。謝謝所有