2012-11-09 150 views
9

我有下面的简单代码来用Maven测试FindBugs @NonNull注释。我执行将findbugs设置为默认值,作为包下的所有类的默认值

mvn clean install 

并正确构建失败,因为print(null)违反了非空的状态。

可以使用类注解

@DefaultAnnotation(NonNull.class) 

如何设置NonNull默认给定包下的所有类中的所有方法的参数(和子集NonNull作为默认的一类中的所有方法的参数包)?

src/main/java/test/Hello.java

package test; 
import edu.umd.cs.findbugs.annotations.NonNull; 
public class Hello { 
    static public void print(@NonNull Object value) { 
     System.out.println("value: " + value.toString()); 
    } 

    static public void main(String[] args) { 
     if (args.length > 0) { 
      print(args[0]); 
     } else { 
      print(null); 
     } 
    } 
} 

pom.xml

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>hello</groupId> 
    <artifactId>hello</artifactId> 
    <version>1.0</version> 

    <dependencies> 
    <dependency> 
     <groupId>net.sourceforge.findbugs</groupId> 
     <artifactId>annotations</artifactId> 
     <version>1.3.2</version> 
    </dependency> 
    <dependency> 
     <groupId>net.sourceforge.findbugs</groupId> 
     <artifactId>jsr305</artifactId> 
     <version>1.3.7</version> 
    </dependency> 
    </dependencies> 

    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <configuration> 
      <source>1.6</source> 
      <target>1.6</target> 
     </configuration> 
     </plugin> 
     <plugin> 
     <groupId>org.codehaus.mojo</groupId> 
     <artifactId>findbugs-maven-plugin</artifactId> 
     <version>2.5.2</version> 
     <configuration> 
      <includeTests>true</includeTests> 
     </configuration> 
     <executions> 
      <execution> 
      <phase>compile</phase> 
      <goals> 
       <goal>check</goal> 
      </goals> 
      </execution> 
      <execution> 
      <id>findbugs-test-compile</id> 
      <phase>test-compile</phase> 
      <goals> 
       <goal>check</goal> 
      </goals> 
      </execution> 
     </executions> 
     </plugin> 
    </plugins> 
    </build> 
</project> 

回答

15

您可以为单个包做到这一点,但我还没有找到一个办法把它传播到子包。对于方法参数,请使用内置包注释@ParametersAreNonnullByDefault。将注释应用于程序包目录内的package-info.java文件中的程序包。

请注意,我正在使用来自JSR-305javax.annotation注释,它们是FindBugs的荣誉。

com/example/foo/package-info.java

/** 
* Package that doesn't allow null values as method parameters. 
*/ 
@ParametersAreNonnullByDefault 
package com.example.foo; 

import javax.annotation.ParametersAreNonnullByDefault; 

因为你需要创建自己的注释字段和方法的返回值。我通过复制ParametersAreNonnullByDefault的源文件并更改ElementType枚举来完成此操作。

com/example/util/FieldsAreNonnullByDefault.java

package com.example.util; 

import java.lang.annotation.Documented; 
import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

import javax.annotation.Nonnull; 
import javax.annotation.meta.TypeQualifierDefault; 

/** 
* Applies the {@link Nonnull} annotation to every class field unless overridden. 
*/ 
@Documented 
@Nonnull 
@TypeQualifierDefault(ElementType.FIELD) // <-- use METHOD for return values 
@Retention(RetentionPolicy.RUNTIME) 
public @interface FieldsAreNonnullByDefault 
{ 
    // nothing to add 
} 

我开始重写从头开始一个相当复杂的系统,一两个月前,每包都有应用这三个注释(字段,参数和返回值)。避免null值的动机之一就是在适当的情况下使用Null Object模式。这与尽可能多地支持最终字段以及只做一件事的小类实际上保持了代码清洁。

1

您可以通过将这些线在你的package-info.java同时这样对参数的Fileds和方法的返回值:

@DefaultAnnotation(NonNull.class) 
package com.my.package; 

当FindBugs的对在该包的代码运行时,所有的方法和字段被假定为非null,除非用@CheckForNull注释它们。

我也不知道如何使这适用于子包。我为每个包做这个。