通过Javac命令的 -processor 参数来执行编译时需要附带的注解处理器,如果有多个注解处理器的话,用逗号分隔。
还可以使用-XprintRounds和-XprintProcessorInfo参数来查看注解处理器运作的详细信息。
NameCheckProcessor的实例只演示了JSR-269嵌入式注解处理API其中的一部分功能,基于这组API支持的项目还有用于效验Hibernate标签使用正确性的Hibernate Validator Annotation Processor(本质上与NameCheckProcessor所做的事情差不多),自动为字段生成getter和setter方法的Project Lombok(根据已有元素生成新的语法树元素)等,
代码如下:
import java.util.EnumSet; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Name; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.util.ElementScanner7; import javax.tools.Diagnostic.Kind; /** * javac NameCheckProcessor.java * javac -processor NameCheckProcessor FT.java * @author kevin * */ //使用*表示支持所有的Annotations @SupportedAnnotationTypes(value = "*") @SupportedSourceVersion(value = SourceVersion.RELEASE_7) public class NameCheckProcessor extends AbstractProcessor { @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); this.nameCheck = new NameCheck(processingEnv); } private NameCheck nameCheck; @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { for (Element element : roundEnv.getRootElements()) { nameCheck.check(element); } } return false; } /** * 程序名称规范的编译器插件 如果程序命名不合规范,将会输出一个编译器的Warning信息 * * @author kevin * */ public static class NameCheck { Messager messager = null; public NameCheckScanner nameCheckScanner; private NameCheck(ProcessingEnvironment processingEnv) { messager = processingEnv.getMessager(); nameCheckScanner = new NameCheckScanner(processingEnv); } /** * 对Java程序明明进行检查,根据《Java语言规范(第3版)》6.8节的要求,Java程序命名应当符合下列格式: * <ul> * <li>类或接口:符合驼式命名法,首字母大写。 * <li>方法:符合驼式命名法,首字母小写。 * <li>字段: * <ul> * <li>类,实例变量:符合驼式命名法,首字母小写。 * <li>常量:要求全部大写 * </ul> * </ul> * * @param element */ public void check(Element element) { nameCheckScanner.scan(element); } /** * 名称检查器实现类,继承了1.6中新提供的ElementScanner6<br> * 将会以Visitor模式访问抽象语法数中得元素 * * @author kevin * */ public static class NameCheckScanner extends ElementScanner7<Void, Void> { Messager messager = null; public NameCheckScanner(ProcessingEnvironment processingEnv) { this.messager = processingEnv.getMessager(); } /** * 此方法用于检查Java类 */ @Override public Void visitType(TypeElement e, Void p) { scan(e.getTypeParameters(), p); checkCamelCase(e, true); super.visitType(e, p); return null; } /** * 检查传入的Element是否符合驼式命名法,如果不符合,则输出警告信息 * * @param e * @param b */ private void checkCamelCase(Element e, boolean initialCaps) { String name = e.getSimpleName().toString(); boolean previousUpper = false; boolean conventional = true; int firstCodePoint = name.codePointAt(0); if (Character.isUpperCase(firstCodePoint)) { previousUpper = true; if (!initialCaps) { messager.printMessage(Kind.WARNING, "名称:" + name + " 应当已小写字符开头", e); return; } } else if (Character.isLowerCase(firstCodePoint)) { if (initialCaps) { messager.printMessage(Kind.WARNING, "名称:" + name + " 应当已大写字母开否", e); return; } } else { conventional = false; } if (conventional) { int cp = firstCodePoint; for (int i = Character.charCount(cp); i < name.length(); i += Character.charCount(cp)) { cp = name.codePointAt(i); if (Character.isUpperCase(cp)) { if (previousUpper) { conventional = false; break; } previousUpper = true; } else { previousUpper = false; } } } if (!conventional) { messager.printMessage(Kind.WARNING, "名称:" + name + "应当符合驼式命名法(Camel Case Names)", e); } } /** * 检查方法命名是否合法 */ @Override public Void visitExecutable(ExecutableElement e, Void p) { if (e.getKind() == ElementKind.METHOD) { Name name = e.getSimpleName(); if (name.contentEquals(e.getEnclosingElement().getSimpleName())) { messager.printMessage(Kind.WARNING, "一个普通方法:" + name + " 不应当与类名重复,避免与构造函数产生混淆", e); checkCamelCase(e, false); } } super.visitExecutable(e, p); return null; } /** * 检查变量是否合法 */ @Override public Void visitVariable(VariableElement e, Void p) { /* 如果这个Variable是枚举或常量,则按大写命名检查,否则按照驼式命名法规则检查 */ if (e.getKind() == ElementKind.ENUM_CONSTANT || e.getConstantValue() != null || heuristicallyConstant(e)) { checkAllCaps(e); } else { checkCamelCase(e, false); } super.visitVariable(e, p); return null; } /** * 大写命名检查,要求第一个字符必须是大写的英文字母,其余部分可以下划线或大写字母 * * @param e */ private void checkAllCaps(VariableElement e) { String name = e.getSimpleName().toString(); boolean conventional = true; int firstCodePoint = name.codePointAt(0); if (!Character.isUpperCase(firstCodePoint)) { conventional = false; } else { boolean previousUnderscore = false; int cp = firstCodePoint; for (int i = Character.charCount(cp); i < name.length(); i += Character.charCount(cp)) { cp = name.codePointAt(i); if (cp == (int) ‘_‘) { if (previousUnderscore) { conventional = false; break; } previousUnderscore = true; } else { previousUnderscore = false; if (!Character.isUpperCase(cp) && !Character.isDigit(cp)) { conventional = false; break; } } } } if (!conventional) { messager.printMessage(Kind.WARNING, "常量:" + name + " 应该全部以大写字母" + "或下划线命名,并且以字符开否", e); } } /** * 判断一个变量是否是常量 * * @param e * @return */ private boolean heuristicallyConstant(VariableElement e) { if (e.getEnclosingElement().getKind() == ElementKind.INTERFACE) { return true; } else if (e.getKind() == ElementKind.FIELD && e.getModifiers().containsAll(EnumSet.of(javax.lang.model.element.Modifier.FINAL, javax.lang.model.element.Modifier.STATIC, javax.lang.model.element.Modifier.PUBLIC))) { return true; } return false; } } } }
import java.util.ArrayList; import java.util.List; public class FT { public static class A_B_C { } public static String ab_sd=""; public static int method(List<Integer> list) { System.out.println("method(List<Integer>list)"); return 1; } public static void main(String[] args) { method(new ArrayList<Integer>()); Long aLong = 2l; Integer aInteger = 1; Integer bInteger = 1; System.out.println(aLong.equals(aInteger + bInteger)); System.out.println(aInteger.equals(1L)); System.out.println("true"); } }
javac NameCheckProcessor.java
javac -processor NameCheckProcessor FT.java
FT.java:4: 警告: 名称:FT应当符合驼式命名法(Camel Case Names)
public class FT {
^
1 个警告
原文:http://blog.csdn.net/kevin_luan/article/details/23091255