自定义一个注解,如果此注解需要在编译期检查注解相关的值,可以自定义一个Annotation的处理类,该类在javax.annotation.processing包中,示例如下:

1)自定义一个annotation ,如Version.java

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

/**
 * Created by terryrao on 5/24/2015.
 */
//@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
@Inherited
@Documented
public @interface Version {
int major () default 1; //主版本号
int minor () default 0; //子版本号

}


建立处理类,当版本的主版本号或者子版本号为负数时,编译不通过。如VersionProcessor.java

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import java.util.Set;

/**
 * Created by terryrao on 5/24/2015.
 */
@SupportedAnnotationTypes({"org.raowei.test.annotaionprocessor.annotaions.Version"})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class VersionProcessor extends AbstractProcessor{

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement currentAnnotation : annotations) {
            Name qualifiedName = currentAnnotation.getQualifiedName();
            if (qualifiedName.contentEquals("org.raowei.test.annotaionprocessor.annotaions.Version")){
                Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(currentAnnotation);
                for (Element element : annotatedElements) {
Version v = element.getAnnotation(Version.class);
                    int major = v.major();
                    int minor = v.minor();
                    if(major < 0 || minor < 0) {
                        String errMsg = "Version cannot be negative. major = " + major + " minor = " + minor;
Messager messager = this.processingEnv.getMessager();
messager.printMessage(Diagnostic.Kind.ERROR,errMsg,element);
}
                }
            }
        }
return Boolean.TRUE;
}


}

3.服务注册文件 :在resources 下面新增META-INF/services文件夹,新建javax.annotation.processing.Processor 增加自定义处理类的全包名

com.test.annotations.processor.VersionProcessor


4.使用maven打包成jar.

        需要注意的是要加上<compilerArgument>-proc:none</compilerArgument>,否则会报错

 

pom.xml

<build>
  <plugins>
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>2.5.1</version>
      <configuration>
        <source>1.8</source>
        <target>1.8</target>
<!-- Disable annotation processing for ourselves.-->
<compilerArgument>-proc:none</compilerArgument>
      </configuration>
    </plugin>
  </plugins>
</build>


5.完成后可以在其它项目中引用Version,编译器就会检查,如果不通过就会打印error,如下

@Version(major = -1,minor = -1)
public class PoiUtils {

	/**
	 * 从Cell里面获即一个单元格样式,并保留该单元格原来的样式
	 * 
	 * @param cell
	 * @return
	 */
	public static CellStyle getCellStyle(Cell cell) {
		Workbook workbook = cell.getRow().getSheet().getWorkbook();
		CellStyle cellStyle = workbook.createCellStyle();
		cellStyle.cloneStyleFrom(cell.getCellStyle()); // 保留原来的格式
		return cellStyle;
	}

	/**
	 * 从Sheet 中获取指定行,如果没有就创建,有就直接返回已存在的
	 * 
	 * @param sheet 从中获取行的表
	 * @param index 行索引(从0开始)
	 * @return Row
	 */
	public static Row getRow(Sheet sheet, int index) {
		return sheet.getRow(index) == null ? sheet.createRow(index) : sheet.getRow(index);
	}

	/**
	 * 从Row中获取指定单元格,如果没有就创建,有就直接返回已存在的
	 * 
	 * @param row 从中获取单元格的行
	 * @param index 列索引(从0开始)
	 * @return Cell
	 */
	public static Cell getCell(Row row, int index) {
		return row.getCell(index) == null ? row.createCell(index) : row.getCell(index);
	}

}

使用maven打包就会出现错误提示,方便编译时检查错误:AbstractProcessor 用法示例_用法示例

AbstractProcessor 用法示例_javase_02另附参考连接如下:

http://developer.51cto.com/art/201001/177878.htm


http://types.cs.washington.edu/checker-framework