2013-01-07 122 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会很烦人。 –