Java注解

1/7/2022 Java后端

在面向对象中,Java的注解使用

# Java注解

JAVA 中有以下几个『元注解』:

  • @Target:注解的作用目标
  • @Retention:注解的生命周期
  • @Documented:注解是否应当被包含在 JavaDoc 文档中
  • @Inherited:是否允许子类继承该注解

# @Target

@Target 用于指明被修饰的注解最终可以作用的目标是谁

@Target(value = {ElementType.FIELD})

其中,ElementType 是一个枚举类型,有以下一些值:

  • ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上
  • ElementType.FIELD:允许作用在属性字段上
  • ElementType.METHOD:允许作用在方法上
  • ElementType.PARAMETER:允许作用在方法参数上
  • ElementType.CONSTRUCTOR:允许作用在构造器上
  • ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
  • ElementType.ANNOTATION_TYPE:允许作用在注解上
  • ElementType.PACKAGE:允许作用在包上

# @Retention

@Retention 用于指明当前注解的生命周期,它的基本定义如下:

@Retention(value = RetentionPolicy.RUNTIME

这里的 RetentionPolicy 依然是一个枚举类型,它有以下几个枚举值可取:

  • RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件
  • RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件
  • RetentionPolicy.RUNTIME:永久保存,可以反射获取

# @Documented

@Documented 注解修饰的注解,当我们执行 JavaDoc 文档打包时会被保存进 doc 文档,反之将在打包时丢弃。

# @Inherited

@Inherited 注解修饰的注解是具有可继承性的,也就说我们的注解修饰了一个类,而该类的子类将自动继承父类的该注解。

# 例子

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

/**
 * @author Codeyang
 * @date 2022/1/8
 */
@Target(value = {ElementType.FIELD,ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Hello {
    String value();
}
    @Test
    @Hello("hello")
    public  void TestAnnotationHello() throws NoSuchMethodException {
        Class clazz = MyController.class;
        Method method = clazz.getMethod("TestAnnotationHello");
        System.out.println(method);
        Hello hello= method.getAnnotation(Hello.class);
        System.out.println(hello);
    }

输出:

public void annotation.MyController.TestAnnotationHello() throws java.lang.NoSuchMethodException
@annotation.Hello(value=hello)

# 实现根据注解匹配方法

package annotation;

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

@Target({ElementType.TYPE,ElementType.METHOD})//当前注解可以用在类,接口,枚举或方法上
@Retention(RetentionPolicy.RUNTIME) //JVM运行时期可以通过反射获取注解值
public @interface RequestMapping {//一个注解
    String value() default "good";//是一个字段值
}
@RequestMapping("/stu")
public class MyController {

    @RequestMapping("/getStuInfo")
    public void select(){
        System.out.println("查询学生信息");
    }

    @RequestMapping("/update")
    public void update() {
        System.out.println("更新学生信息");
    }
    @RequestMapping("/delete")
    public void delete() {
        System.out.println("删除学生信息");
    }


    @Test
    public  void TestAnnotation() {
        String url="/delete";//模拟前端发送的请求路径
        Class clazz=MyController.class;
        if(clazz.isAnnotationPresent(RequestMapping.class)){//判断当前类上是否有RequestMapping注解
            Method methods[]=clazz.getDeclaredMethods();//获取类中所有的方法
            for(Method method:methods){
                if(method.isAnnotationPresent(RequestMapping.class)){//判断当前方法是否有RequestMapping注解
                    RequestMapping requestMapping=method.getAnnotation(RequestMapping.class);//获取注解对象,目的是为了获取注解值
                      if(requestMapping.value().equals(url)){//全部匹配,找到请求对应的方法
                          try {
                              method.invoke(clazz.newInstance());//调用方法
                          } catch (IllegalAccessException e) {
                              e.printStackTrace();
                          } catch (InvocationTargetException e) {
                              e.printStackTrace();
                          } catch (InstantiationException e) {
                              e.printStackTrace();
                          }
                      }
                }
            }
        }
    }

}
Last Updated: 2/11/2022, 2:51:08 PM