C20-注解&自定義注解

注解

相對于注釋,注解能做到更多事情,對于注解更深入的了解還比較少,這里只簡單介紹如何去自定義一個注解,并編寫自己的注解處理器。

自定義一個注解:ExtractInterface

用途:抽取被注解類的public非static的方法,并生成接口

定義注解

//ExtractInterface.Java
/**
 * Created by liaowm5 on 17/7/31.
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface ExtractInterface {
  public String interfaceName(); //指定要生成的接口名
}

定義注解處理器

讓自定義Processor繼承自AbstractProcessor,其核心是實現(xiàn)process方法,用于獲取被注解的對象。

// InterfaceExtractorProcessor.Java
/**
 * Created by liaowm5 on 17/7/31.
 */
@AutoService(Processor.class)
public class InterfaceExtracorProcessor extends AbstractProcessor {

    private Set<String> supportedAnnotationTypes = new HashSet<String>();

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        supportedAnnotationTypes.add(ExtractInterface.class.getCanonicalName());
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        Messager messager = processingEnv.getMessager();
        for (TypeElement typeElement : annotations) {
            for (Element element : roundEnv.getElementsAnnotatedWith(typeElement)) {
                ExtractInterface annot = element.getAnnotation(ExtractInterface.class);

                if (annot != null) {
                    String interfaceName = annot.value();
                    messager.printMessage(Diagnostic.Kind.NOTE, "ExtractInterface = " + interfaceName);
                    messager.printMessage(Diagnostic.Kind.NOTE, "modifiers=" + element.getModifiers() + " name=" + element.getSimpleName());
                    for (Element e : element.getEnclosedElements()) {
                        messager.printMessage(Diagnostic.Kind.NOTE, "modifiers=" + e.getModifiers() + " name=" + e.getSimpleName());
                    }

                    try {
                        List<MethodSpec> methodSpecList = new ArrayList<>();
                        for (Element e : element.getEnclosedElements()) {
                            methodSpecList.add(MethodSpec.methodBuilder(e.getSimpleName().toString())
                                    .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
                                    .build());
                        }
                        TypeSpec interfaceJavaFile = TypeSpec.interfaceBuilder(interfaceName)
                                .addModifiers(Modifier.PUBLIC)
                                .addMethods(methodSpecList)
                                .build();

                        JavaFile javaFile = JavaFile.builder(ExtractInterface.class.getPackage().getName(), interfaceJavaFile)
                                .build();

                        messager.printMessage(Diagnostic.Kind.NOTE, "packageName = " + ExtractInterface.class.getPackage().toString());
                        javaFile.writeTo(new File("/Users/liaowm5/Desktop/Learn/Learn/annotationsTest/lib/"));
                        messager.printMessage(Diagnostic.Kind.NOTE, javaFile.toString());
                    } catch (Exception e) {
                        messager.printMessage(Diagnostic.Kind.ERROR, e.toString());
                    }
                }
            }
        }
        return false;
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return supportedAnnotationTypes;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }
}

注解本來可以用apt工具集成,你可以自定義注解處理器繼承自Processor并重寫Process方法也可以達到效果。但是在Intellij idea上用maven構(gòu)建時出了一堆問題,只好繼承AbstractProcessor。折中的方法: 用谷歌的一個注解框架(com.google.auto.service)并打包生成Jar包。導入你需要使用自定義注解的項目中,要注意的是,Intellij idea需要手動配置注解處理器。

使用自定義注解

@ExtractInterface("IMultipler")
public class Multiplier {

    public Multiplier() {

    }

    public int multiply(int x, int y) {
        int total = 0;
        for (int i = 0; i < x; i++)
            total = add(total, y);
        return total;
    }

    public int add(int x, int y) {
        return x + y;
    }

    public static void main(String args[]) {
        Multiplier m = new Multiplier();
        System.out.println("11*6 = " + m.multiply(11, 6));
    }
}

在idea項目結(jié)構(gòu)中導入剛剛生成的自定義注解jar包


導入自定義注解Jar包

編譯整個項目,就可以看到注解處理器在編譯時輸出的信息

Build信息

同時生成了IMultipler接口


IMultipler.Java

注意: IntelliJ Idea默認沒有開啟注解處理,需要在Preferences -> Build,Extension,Deployment -> complier -> Annotation Processors 勾選Enable annotation processing

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容