下面表示注解作用在Class类上:
@Target(ElementType.TYPE)
public @interface Test {
}
下面使用CLASS级别,表示编译时,保留注解信息到字节码:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface Test {
}
@Retention还能指定两种,一种SOURCE级别,只在源码中,不维持至字节码:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Test {
}
还有一种是RUNTIME级别:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}
CLASS在字节码中的标记为 RuntimeInvisibleAnnotations,JVM不会加载它 RUNTIME在字节码中的标记为 RuntimeVisibleAnnotations,JVM会加载,所以可以通过反射获取 SOURCE 字节码中没有注解信息,使用此注解,类似于注释
一般都是使用RUNTIME级别
定义一个注解,并需要实现一个方法:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
int value();
}
在类中使用,需要传入value的值,可以通过反射获取:
@Test(100)
public class TestAnnotation {
public static void main(String[] args) {
Class<TestAnnotation> testAnnotationClz = TestAnnotation.class;
Test annotation = testAnnotationClz.getAnnotation(Test.class);
int value = annotation.value();
System.out.println(value);
}
}
还可以在方法后面,使用default关键字设置默认值:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
int value() default 10;
}
APT全名为Annotation Processor Tools,注解编译工具,使用它可以通过获取注解信息来自动生成相应的代码
Module类型选择"Java or Kotlin Library",创建一个注解:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
String value() default "";
}
同样是"Java or Kotlin Library",gradle配置修改如下:
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
dependencies {
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc4'
compileOnly 'com.google.auto.service:auto-service:1.0-rc4'
//依赖注解module
implementation project(path: ':lib_annotation')
}
创建Processor继承至AbstractProcessor,并实现方法:
@AutoService(Processor.class)
@SupportedAnnotationTypes({"com.aruba.lib_annotation.TestAnnotation"})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class TestProcessor extends AbstractProcessor {
private Messager messager;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
//获取messager
messager = processingEnv.getMessager();
messager.printMessage(Diagnostic.Kind.NOTE, "init");
}
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
messager.printMessage(Diagnostic.Kind.NOTE, "process");
//获取所有使用TestAnnotation注解的元素集合
Set<? extends Element> elementsAnnotatedWith = roundEnvironment.getElementsAnnotatedWith(TestAnnotation.class);
for (Element element : elementsAnnotatedWith) {
messager.printMessage(Diagnostic.Kind.NOTE, element.getSimpleName());
}
return true;
}
}
在主Module并添加依赖:
dependencies {
implementation project(path: ':lib_annotation')
annotationProcessor project(':lib_complier')
}
使用注解:
class Main {
@TestAnnotation
String test;
public static void main(String[] args) {
}
}
编译时,就可以看到打印信息了: