java注解:
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。 注解是元数据的一种形式,提供有关
于程序但不属于程序本身的数据。注解对它们注解的代码的操作没有直接影响。
注解申明
Java中所有的注解,默认实现 Annotation 接口:
package java.lang.annotation;
public interface Annotation {
boolean equals(Object obj);
int hashCode();
String toString();
Class<? extends Annotation> annotationType();
}
与声明一个"Class"不同的是,注解的声明使用 @interface 关键字。一个注解的声明如下:
public @interface Lance{
}
元注解
注解上的注解,即为元注解,一般情况下,常用的元注解有两个:@Target @Retention (另外还有@Documented 与 @Inherited 元注解,前者用于被javadoc工具提取成文档,后者表示允许子类 继承父类中定义的注解)
@target 元注解 定义了 该注解可以作用的场景:
ElementType.ANNOTATION_TYPE 可以应用于注解类型。
ElementType.CONSTRUCTOR 可以应用于构造函数。
ElementType.FIELD 可以应用于字段或属性。
ElementType.LOCAL_VARIABLE 可以应用于局部变量。
ElementType.METHOD 可以应用于方法级注解。
ElementType.PACKAGE 可以应用于包声明。
ElementType.PARAMETER 可以应用于方法的参数。
ElementType.TYPE 可以应用于类的任何元素。
@Retention 元注解 标记了 该注解被保留的级别*(
@Retention
三个值中
SOURCE < CLASS < RUNTIME
,即
CLASS
包含了
SOURCE
,
RUNTIME
包含
SOURCE
、
CLASS
)
RetentionPolicy.SOURCE - 标记的注解仅保留在源级别中,并被编译器忽略。 (
作用于源码级别的注解,可提供给
IDE
语法检查(@Intdef)、
APT
等场景使用,编译成jclass的时候,注解消失
)
RetentionPolicy.CLASS - 标记的注解在编译时由编译器保留,但 Java 虚拟机(JVM)会忽略。(
字节码操作,
AspectJ
、热修复
Roubust中应用此场景。接修改字节码
Class
文件以达到修改代码执行逻辑的目的
)
RetentionPolicy.RUNTIME - 标记的注解由 JVM 保留,因此运行时环境可以使用它 。(
结合反射,动态实现功能,获取注解中所有信息
)
//@Target(ElementType.TYPE) 只能在类上标记该注解 @Target({ElementType.TYPE,ElementType.FIELD}) // 允许在类与类属性上标记该注解
@Retention(RetentionPolicy.SOURCE) //注解保留在源码中
public @interface Lance {
}
注解处理程序---Annotation Processor Tools
新建java-lib
包名下面新建类
LanceProcessor 继承自
AbstractProcessor
package com.qshn.lib;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
/**
* 注解处理程序在什么阶段执行?
*
* .java -> javac -> .class
* Source级别可以被注解处理程序使用,因为 source级别只保留在源码里面 而javac 就是要去解析源码 去运行注解处理程序
* 所以注解只需要保留到source级别就可以去给APT使用了,可以给注解处理程序使用了
*
*
*/
@SupportedAnnotationTypes("com.qshn.annotation.Lance")
public class LanceProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
Messager messager = processingEnv.getMessager();
messager.printMessage(Diagnostic.Kind.NOTE, "================================");
System.out.println("你是111吗?");
System.out.println("====dsfdssdfsdfsdfsdfsdfdsf22222===");
return false;
}
}
在main 下面 新建 resources 文件夹 再依次新建 META ——》services 文件夹 最后新建文件 javax.annotation.processing.processor 在该文件里面写入 注解处理程序 全路径
在注解处理类中 可以通过
@SupportedAnnotationTypes("com.qshn.annotation.Lance") 来限定需要处理的注解
在
process中 通过
processingEnv.getMessager() 打印相关信息 也可以进行一系列操作 比如联网之类
编译 之后 可以发现 经javac 之后 打印了 信息