-
Annotation 其实就是代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过使用 Annotation,程序员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
-
Annotation 可以像修饰符一样被使用,可用于修饰包,类,构造器,方法,成员变量,参数,局部变量的声明,这些信息被保存在 Annotation 的 "name=value" 对中。
在编译时进行格式检查(JDK内置的三个基本注解)
@Override: 限定重写父类方法,该注解只能用于方法
@Deprecated: 用于表示所修饰的元素(类,方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
@SuppressWarnings: 抑制编译器警告
JDK5.0 提供了4个标准的 meta-annotation 类型,分别是:
Retention
Target
Documented
Inherited
@Retention: 只能用于修饰一个 Annotation 定义,用于指定该 Annotation 的生命周期, @Rentention 包含一个 RetentionPolicy 类型的成员变量,使用
@Rentention 时必须为该 value 成员变量指定值:
RetentionPolicy.SOURCE: 在源文件中有效(即源文件保留),编译器直接丢弃这种策略的注释
RetentionPolicy.CLASS: 在 class 文件中有效(即class保留),当运行Java程序时, JVM不会保留注解。这是默认值
RetentionPolicy.RUNTIME: 在运行时有效(即运行时保留),当运行Java程序时,JVM会保留注释。程序可以通过反射获取该注释。
@Inherited: 被它修饰的 Annotation 将具有继承性。如果某个类使用了被@Inherited 修饰的 Annotation, 则其子类将自动具有该注解。
比如: 如果把标有 @Inherited 注解的自定义的注解标注在类级别上,子类则可以继承父类类级别的注解
实际应用中,使用较少
## AnnotationTest.java
package com.klvchen.java1;
import org.junit.Test;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Date;
public class AnnotationTest {
public static void main(String[] args){
Person p = new Student();
p.walk();
Date date = new Date(2020, 10, 11);
System.out.println(date);
@SuppressWarnings("unused")
int num = 10;
@SuppressWarnings({ "unused", "rawtypes" })
ArrayList list = new ArrayList();
}
@Test
public void testGetAnnotation(){
Class clazz = Student.class;
Annotation[] annotations = clazz.getAnnotations();
for (int i = 0; i < annotations.length; i++){
System.out.println(annotations[i]);
}
}
}
@MyAnnotation(value="hi")
@MyAnnotation(value="abc")
class Person{
private String name;
private int age;
public Person() {
}
@MyAnnotation
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@MyAnnotation
public void walk(){
System.out.println("人走路");
}
@MyAnnotation
public void eat(){
System.out.println("人吃饭");
}
}
interface Info{
void show();
}
class Student extends Person implements Info{
@Override
public void walk(){
System.out.println("学生走路");
}
@Override
public void show(){
}
}
class Generic<@MyAnnotation T>{
public void show() throws @MyAnnotation RuntimeException{
ArrayList<@MyAnnotation String> list = new ArrayList<>();
int num = (@MyAnnotation int) 10L;
}
}
## MyAnnotation.java
package com.klvchen.java1;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
@Inherited
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,TYPE_PARAMETER,TYPE_USE})
public @interface MyAnnotation {
String value() default "hello";
}
## MyAnnotations.java
package com.klvchen.java1;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
public @interface MyAnnotations {
MyAnnotation[] value();
}