注解 Annotation

前言

Java 版本 Java1.8。

介绍

什么是注解?

注解是 JDK1.5 引入的新特性,它可以用来为程序元素(类、方法、成员变量等)设置元数据(MetaData),元数据可以是任何数据,包括文档、代码、编译器指令等,注解的存在对程序本身没有任何影响,但可以被一些工具读取和使用,例如:编译器可以用注解来检测错误或警告信息,编译器可以根据注解生成代码,也可以利用注解来生成文档,还有一些第三方工具可以通过注解来生成代码。

也是一种特殊的接口,它继承了 java.lang.annotation.Annotation 接口(Annotation 接口是所有注解的父接口),并且注解的定义方式和接口的定义方式相似,但它的定义需要使用 @interface 关键字。

更是一种特殊的类,作用类似于注释,可以标记一个类、方法、变量和参数等不同位置。

在实际开发中,注解可以分为三类:

  • JDK 自带的注解
  • 第三方注解
  • 自定义注解

尤其是现在流行的基于注解式开发中,所以对于掌握注解是非常有必要的。

JDK 自带的注解(常见)

  • @Override:表示当前方法覆盖了父类的方法,如果不小心写错了方法名,编译器会报错,这样就避免了出现错误。
  • @Deprecated:表示当前方法已经过时,不建议使用,如果使用了编译器会报错,但是不影响使用。
  • @SuppressWarnings:表示当前方法忽略警告,如果使用了编译器会报错,但是不影响使用。
  • @Retention:表示当前注解的生命周期,有三个值:RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME。
  • @Target:表示当前注解可以标记的位置,有九个值:ElementType.TYPE、ElementType.FIELD、ElementType.METHOD、ElementType.PARAMETER、ElementType.CONSTRUCTOR、ElementType.LOCAL_VARIABLE、ElementType.ANNOTATION_TYPE、ElementType.PACKAGE、ElementType.TYPE_PARAMETER、ElementType.TYPE_USE。
  • @Documented:表示当前注解可以被 javadoc 工具读取。
  • @Repeatable:表示当前注解可以重复标记。

自定义注解

学学自带注解

既然要自定义注解,肯定是要先看看现有的注解长什么样子了。就以常见的 @Override 注解为例

  • 看看注解 @Override

它的定义如下:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

首先可以看到非常明显的特点:这不就是一个类吗?

但是它的定义方式和类的定义方式又不一样,它的定义方式和接口的定义方式相似,但是它的定义需要使用 @interface 关键字。

而且在类的上面也有两个注解:@Target 和 @Retention,这两个注解也是注解。

  • 看看注解 @Target

@Target 注解的定义如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    ElementType[] value();
}

可以看到 @Target 注解的定义也是一个类,而且它的定义方式和 @Override 注解的定义方式相似,但是它却多了一个注解:@Documented。

还多了一个方法:ElementType[] value(),这个方法的返回值是一个枚举数组,表示当前注解可以标记的位置。

@Target作用是:表示当前注解可以标记的位置

  • 看看注解 @Retention

@Retention 注解的定义如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

@Retention 作用是:表示当前注解的生命周期。

一般都会使用 RetentionPolicy.RUNTIME,表示当前注解在源码阶段、编译阶段和运行阶段都有效。

  • 看看注解 @Documented

@Documented 注解的定义如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

@Documented 作用是:表示当前注解可以被 javadoc 工具读取。

照猫画虎

这就是传说中的无限套娃吗?

其实上面那些注解除了 @Override 注解是用来标记方法的,其他的注解都是用来标记注解的,也叫做元注解。

可见要想定义一个注解,就需要最基本的元注解:@Target 和 @Retention。

话不多说,来吧:

@Target(ElementType.METHOD) // 表示当前注解可以标记的位置,可以作用在方法上
@Retention(RetentionPolicy.SOURCE) // 表示当前注解的生命周期,表示当前注解只在源码阶段有效
public @interface MyAnnotation {
}

在注解 @Target 上面有一个 ElementType[] value() 方法,这个方法的返回值是一个枚举数组,表示当前注解可以标记的位置,也就是说这个注解可以标记在类、方法、成员变量、参数等位置,但是我们这里只需要标记在方法上面,所以我们只需要把 ElementType.METHOD 放到这个数组里面就可以了。

@Target({ElementType.METHOD, ElementType.TYPE}) // 可以作用在方法上和类上
@Retention({RetentionPolicy.SOURCE, RetentionPolicy.CLASS}) // 表示当前注解只在源码阶段和编译阶段和运行阶段有效
public @interface MyAnnotation {
}

在看 JDK 自带的元注解的时候看到注解 @Target 上面有一个 ElementType[] value() 方法,为什么传值的时候不需要指定这个方法的名字呢?

因为这个方法的名字是 value,而且这个方法是唯一的,所以可以省略。

@Target(value = {ElementType.METHOD, ElementType.TYPE})
@Retention(value = {RetentionPolicy.SOURCE, RetentionPolicy.CLASS})
public @interface MyAnnotation {
}

需要注意的是只有方法名为 value 的方法才可以省略,其他的方法都不能省略。

使用自定义注解

根据上面的过程自定义一个注解:

@Target(ElementType.FIELD) // 可以作用在成员变量上
@Retention(RetentionPolicy.RUNTIME) // 当前注解在源码阶段、编译阶段和运行阶段都有效
public @interface MyAnnotation {
    String value() default "hello";
    String name() default "world";
}

在定义一个类:

@Getter
@Setter
public class Person {
    @MyAnnotation
    private String name;
    @MyAnnotation(value = "hi", name = "java")
    private String age;
}

然后在测试类中使用反射获取注解:

public static void main(String[] args) {
    Class<Person> personClass = Person.class;
    for (Field field : personClass.getFields()) {
        MyAnnotation myAnnotation = field.getAnnotation(MyAnnotation.class);
        String value = myAnnotation.value();
        String name = myAnnotation.name();
        System.out.println("字段名:" + field.getName() + " 的注解值:" + value + " 注解名:" + name);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值