Java注解(Annotation)

本文和大家聊聊Java注解

什么是注解?

咱们先来看看Java官方定义:

注解是一种元数据形式,提供程序本身以外的数据,对代码没有直接的影响。

这是说的啥?相信很多朋友初次看到注解定义都会有这样的反应。

那有没有一种通俗易懂的定义或是比喻呢?
我觉得可以把注解比喻成电子标签,因为电子标签可以为粘贴它的物品,提供解释与说明,这和注解的作用很相似。

Java注解(Annotation)_第1张图片
电子标签

如何声明一个注解?

下面咱们来声明一个注解,代码如下:

public @interface TestAnnotation {
    int id();
    Srting value() default "N/A"
}

咱们来分析一下上面的代码:

  1. @interface:注解关键字
  2. TestAnnotation:注解名
  3. id、value:注解的参数

哪些类型可以作为注解的参数?

注解的参数可支持数据类型:

  • 所有基本数据类型(int,float,double,boolean,byte,char,long,short)
  • String 类型
  • Class类型
  • 以上所有类型的数组

在讲解如何使用注解之前,咱们先来看看什么是元注解?这对后面更好的理解注解很有助益

什么是元注解?

官方的定义:用于解释注解的注解

咱们前面把注解比喻成电子标签
这里可以把元注解看作电子标签的说明书,因为说明书会描述电子标签的用途和使用范围,这个元注解的作用很相似。

下面举个使用元注解的例子:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
    int id();
    Srting value() default ''N/A''
}

元注解有哪些?

下面咱们看看有哪些元注解,以及它的作用

  • @Retention指定注解的保留方式:
    RetentionPolicy.SOURCE - 标识的注解仅保留在源代码级别,并被编译器忽略。
    RetentionPolicy.CLASS - 标识的注解在编译时由编译器保留,但被Java虚拟机(JVM)忽略。
    RetentionPolicy.RUNTIME - 标识的注解由JVM保留,以便运行时环境使用它。

  • @Documented 在任何时使用指定的注解,这些元素都应该使用Javadoc工具进行记录。(默认情况下,Javadoc中不包含注释)

  • @Target 用来限制注解的用途。其值:
    ElementType.ANNOTATION_TYPE 可以应用于注释类型。
    ElementType.CONSTRUCTOR 可以应用于构造函数。
    ElementType.FIELD 可以应用于一个属性。
    ElementType.LOCAL_VARIABLE 可以应用于局部变量。
    ElementType.METHOD 可以应用于方法级别的注释。
    ElementType.PACKAGE 可以应用于包声明。
    ElementType.PARAMETER 可以应用于方法的参数。
    ElementType.TYPE 可以应用于任何类的元素。

  • @Inherited 表示注解类型可以从超类继承。当子类没有这个类型的注解时,查询该类的超父类的注解类型。这个注解只适用于类声明。

  • @Repeatable 表示注解可以多次应用于相同的声明或类型。(Java 8新加入的)

注解的用途

注释有许多用途,其中包括:

  • 编译器信息: 编译器可以使用注解来检测错误或取消警告。
  • 编译时和部署时处理: 软件工具可以处理注解信息以生成代码,XML文件等。
  • 运行时处理: 可在运行时检查。
  • 开发框架:ButterKnife、Retrofit、Dagger、Google的Room

注解的使用

下面咱们通过一个例子,来看看该如何使用注解。

获取注解信息用到了Java反射相关的内容,如有需要,请移步Java反射基础与实践

本例展示在代码中如何使用注解。

第一步,声明一个注解。代码如下:

package com.hys;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SimpleAnnotation {
    int id();
    String description();
}

第二步,在类中使用它,还记得上文中咱们对注解的比喻吗?这一步相当于给类的方法贴一个电子标签。代码如下:

package com.hys;

public class User {

    private String mName;
    private int mAge;

    @SimpleAnnotation(id=1, description="Get user name")
    public String getName(){
        return mName;
    }

    @SimpleAnnotation(id=2, description="Get User age")
    public int getAge(){
        return mAge;
    }
}

第三步,在程序运行时,读取注解所提供的方面描述信息。代码如下:

package com.hys;

import java.lang.reflect.Method;

public class Main {
    public static void main(String[] args) {

        try {
            Class userClazz = Class.forName("com.hys.User");

            Method[] methods = userClazz.getDeclaredMethods();
            for(Method method : methods){
                if(!method.isAnnotationPresent(SimpleAnnotation.class))
                    continue;
                
                SimpleAnnotation annotation = method.getAnnotation(SimpleAnnotation.class);
                System.out.println("Method name:" + method.getName());
                System.out.println("Method id:" + annotation.id());
                System.out.println("Method description:" + annotation.description());
            }
        }
        catch (Throwable e) {
            System.err.println(e);
        }
    }
}

执行结果:

Method name:getName
Method id:1
Method description:Get user name
Method name:getAge
Method id:2
Method description:Get User age

总结, 注解是为它依附的对象(类、方法、属性、方法的参数、局部变量、包)提供解释与说明;元注解是说明注解的用途和使用范围。


我是青岚之峰,如果读完后有所收获,欢迎点赞加关注!

你可能感兴趣的:(Java注解(Annotation))