注解

Annotation

  • 注解如同标签
  • 对类行为的某些角度进行评价与解释
  • 注解通过反射获取

注解的创建

public @interface TestAnnotation{
}

注解的使用

@TestAnnotation
public class Test{
}

元注解

可以注解到其他注解上的注解,也就是基本注解,可以用来规范注解的一些行为

  • @Retention --> 注解的存活周期
    • RetentionPolicy.SOURCE 注解将被编译器丢弃
    • RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃
    • RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。
  • @Documented --> 能将注解保存到Javadoc中
  • @Target --> 注解应用的地方
    • ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
    • ElementType.CONSTRUCTOR 可以给构造方法进行注解
    • ElementType.FIELD 可以给属性进行注解
    • ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
    • ElementType.METHOD 可以给方法进行注解
    • ElementType.PACKAGE 可以给一个包进行注解
    • ElementType.PARAMETER 可以给一个方法内的参数进行注解
    • ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
  • @inherited --> 如果父类使用了此注解,那么子类可以继承此注解
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Test {}

@Test
public class A {}

public class B extends A {}
  • @Repeatable --> Java8新注解,多次应用的注解
@interface Persons {
    Person[]  value();
}

@Repeatable(Persons.class)
@interface Person{
    String role default "";
}

@Person(role="artist")
@Person(role="coder")
@Person(role="PM")
public class SuperMan{
}

容器注解

存放注解的容器,本身也是注解。

注解的属性

注解的属性也叫做成员变量。

  • 注解只有成员变量,没有方法
  • 以无参的方法来声名
  • 方法名为成员名
  • 返回值为成员类型
    • 类型必须是 8 种基本数据类型
    • 接口
    • 注解
    • 以上各类型的数组
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {

    int id();

    String msg();

}

在使用注解的时候,应该为该注解的属性赋值:

@TestAnnotation(id=3,msg="hello annotation")
public class Test {
}

注解中属性可以有默认值,默认值需要用 default 关键值指定:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {

    public int id() default -1;

    public String msg() default "Hi";

}

因此在使用的时候无需再赋初值:

@TestAnnotation()
public class Test {}

如果注解中属性名为value,那么可以省略属性名直接赋值使用

public @interface Check {
    String value();
}

@Check("hi")
int a;

内置注解

  • @Deprecated
  • @Override
  • @SuppressWarnings
  • @FunctionalInterface Java8新特性,函数式接口可以很容易转化为Lamda表达式。

注解与反射

  • 首先可以通过 Class 对象的 isAnnotationPresent() 方法判断它是否应用了某个注解:
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}
  • 然后通过 getAnnotation() 方法来获取 Annotation 对象:
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}
  • 或者是 getAnnotations() 方法:
public Annotation[] getAnnotations() {}
  • 如果获取到的Annotation不为null,则可以调用它的属性方法了:
@TestAnnotation()
public class Test {

    public static void main(String[] args) {

        boolean hasAnnotation = Test.class.isAnnotationPresent(TestAnnotation.class);

        if ( hasAnnotation ) {
            TestAnnotation testAnnotation = Test.class.getAnnotation(TestAnnotation.class);

            System.out.println("id:"+testAnnotation.id());
            System.out.println("msg:"+testAnnotation.msg());
        }
    }
}

程序运行结果:

id:-1
msg:

注解的作用

  • 注解本身对程序运行没有直接关系
  • 注解的存在主要是为编译器或APT(Annotation Processing Tool)使用,而要使用的话需要开发者手动调用方法来提取并处理Annotation的信息

总结

  • 注解的作用是取决于你想要它做什么
MobiusStrip CSDN认证博客专家 Java Java学习之道
欢迎关注微信公众号:【Java学习之道】-记录Java学习路上的点点滴滴;也欢迎来访我的博客:https://www.mmzsblog.cn
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页