Java 基础(Annotation)
-
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(); }