注解
注解是一种对代码进行解释的标签,主要作用是让jvm理解被标注的内容的含义
注解的定义
定义注解使用@interface
关键字
public @interface exampleAnnotation{}
注解只有成员变量,没有方法。注解的成员变量在注解的定义中以“无形参的方法”来生命,方法名定义了该成员变量的名字,返回值定义了成员变量的烈性。在使用时将其赋值
如下所示
public @interface Annotation{
int id();
}
@Annotation(id = 5)
此外,如果注解中只有一个名为value
的属性,使用时,可以在括号中直接输入属性的值
@Annotaion("hello")
元注解
元注解是可以标注到注解上的注解,主要有以下5种
@Retention
这个注解的作用为,说明被标注的注解的存活时间,
有以下取值:
-
RetentionPolicy.SOURCE
: 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。 -
RetentionPolicy.CLASS
: 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。 -
RetentionPolicy.RUNTIME
: 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
@Document
将注解中的元素包含到javado中去
@Target
该注解标注了注解运用的地方
-
ElementType.ANNOTATION_TYPE
可以给一个注解进行注解 -
ElementType.CONSTRUCTOR
可以给构造方法进行注解 -
ElementType.FIELD
可以给属性进行注解 -
ElementType.LOCAL_VARIABLE
可以给局部变量进行注解 -
ElementType.METHOD
可以给方法进行注解 -
ElementType.PACKAGE
可以给一个包进行注解 -
ElementType.PARAMETER
可以给一个方法内的参数进行注解 -
ElementType.TYPE
可以给一个类型进行注解,比如类、接口、枚举
@Inherited
一个类如果被该注解标注过的注解进行注解,它的子类如果没有被任何注解应用的话,那么该子类就继承父类的注解
@Repeateable
表示一个注解可以多次标注元素
注解的提取
想要正确检测类是否被注解标注了,就需要使用反射
首先,先获取类的字节码对象Class,
- public boolean isAnnotationPresent(Class<? extends Annotation> annotaionClass):用于判断类是否被某个注解标注
- public A getAnnotation(Class annotationClass) :获取Annotation对象
- public Annotation[] getAnnotations() :返回所有被标注的注解
如果获取到的注解不为空,就可以获取到注解对象的属性并进行操作了
//注解用于注入成员变量
@Target(ElementType.TYPE)
@interface Value{
int age();
String name();
}
//测试用例Person
@Value(age = 5,name = "Zhangsan")
class Person{
Integer age;
String name;
public Person(String name, Integer age){
this.name = name;
this.age = age;
}
}
public class Test{
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//利用反射获取person的注解
Value value = Person.class.getAnnotation(Value.class);
//利用person的字节码对象获取构造方法
Constructor personConstructor = Person.class.getDeclaredConstructor(String.class, Integer.class);
Person child = (Person) personConstructor.newInstance(value.name(), value.age());
System.out.println(child.age+" "+child.name);
}
}