ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

自定义注解

2022-07-01 22:04:13  阅读:141  来源: 互联网

标签:Class String 自定义 class person 注解 annotation


自定义注解

1. 注解概要描述

注解描述:在 java 源码的类、方法、字段、参数前的特殊“注释”,注解会被编译器直接忽略,注解则可以被编译器打包进入class文件,因此,注解是一种用作标注的“元数据”。

作用:

从JVM的角度看,注解本身对代码逻辑没有任何影响,如何使用注解完全由工具决定。

注解分类:

  1. 编译器使用的注解
  • @Override:让编译器检查该方法是否正确地实现了覆写;
  • @SuppressWarnings:告诉编译器忽略此处代码产生的警告。

这类注解不会被编译进入.class文件,它们在编译后就被编译器扔掉了。

  1. 工具处理 .class 文件使用的注解

比如有些工具会在加载class的时候,对class做动态修改,实现一些特殊的功能。这类注解会被编译进入.class文件,但加载结束后并不会存在于内存中。这类注解只被一些底层库使用,一般我们不必自己处理。

  1. 程序运行期读取的注解

在加载后一直存在于JVM中,这也是最常用的注解。例如,一个配置了@PostConstruct的方法会在调用构造方法后自动被调用(这是Java代码读取该注解实现的功能,JVM并不会识别该注解)。

注解参数类型:

  • 所有基本类型;
  • String;
  • 枚举类型;
  • 基本类型、String、Class以及枚举的数组

2. 注解实现

2.1 定义注解

/**
 * @author Andrew
 * @date 2022/6/16
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Information {
    String name();

    int age();

    String[] hobbies();

    String address() default "中国";
}

注解的参数类似无参数方法,可以用default设定一个默认值。最常用的参数应当命名value

2.2 元注解

可以修饰其他注解的就叫元注解。

  1. Target

@Target可以定义Annotation能够被应用于源码的哪些位置:

  • 类或接口:ElementType.TYPE
  • 字段:ElementType.FIELD
  • 方法:ElementType.METHOD
  • 构造方法:ElementType.CONSTRUCTOR
  • 方法参数:ElementType.PARAMETER
  1. Retention

@Retention定义了Annotation的生命周期

  • 仅编译期:RetentionPolicy.SOURCE
  • 仅class文件:RetentionPolicy.CLASS
  • 运行期:RetentionPolicy.RUNTIME
  1. Repetable

@Repeatable这个元注解可以定义Annotation是否可重复

  1. Inherited

@Inherited定义子类是否可继承父类定义的Annotation

2.3 处理注解

Java的注解本身对代码逻辑没有任何影响。根据@Retention的配置:

  • SOURCE类型的注解在编译期就被丢掉了;
  • CLASS类型的注解仅保存在class文件中,它们不会被加载进JVM;
  • RUNTIME类型的注解会被加载进JVM,并且在运行期可以被程序读取。

注解定义后也是一种class,所有的注解都继承自java.lang.annotation.Annotation,Java提供的使用反射API读取Annotation的方法包括:

判断某个注解是否存在于ClassFieldMethodConstructor

  • Class.isAnnotationPresent(Class)
  • Field.isAnnotationPresent(Class)
  • Method.isAnnotationPresent(Class)
  • Constructor.isAnnotationPresent(Class)

使用反射API读取Annotation:

  • Class.getAnnotation(Class)
  • Field.getAnnotation(Class)
  • Method.getAnnotation(Class)
  • Constructor.getAnnotation(Class)

3. 实践 DEMO

需求:获取方法上注解的具体参数并输出

  1. 定义注解
/**
 * 定义注解
 *
 * @author Andrew
 * @date 2022/6/16
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Information {
    String name();

    int age();

    String[] hobbies();

    String address() default "中国";
}
  1. 使用注解
/**
 * 使用注解
 *
 * @author Andrew
 * @date 2022/6/16
 */
@Component
public class PersonService {


    @Information(name = "Evan", age = 18, hobbies = {"编程", "看电影", "踢足球"})
    public void outputPersonInfo(Person person) {
        if (person != null) {
            System.out.println(person.toString());
        }
    }
}
  1. 赋予注解功能
/**
 * 赋予注解功能
 *
 * @author Andrew
 * @date 2022/6/22
 */
@org.aspectj.lang.annotation.Aspect
@Component
public class Aspect {

    @Before("execution(public void com.zbm.test.controller.PersonService.*(..))")
    public void check() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        // 通过反射获取方法
        Method method = PersonService.class.getMethod("outputPersonInfo", Person.class);
        // 获取方法上的注解
        Information annotation = method.getAnnotation(Information.class);
        // 输出方法内容
        System.out.println("+++++++++++++" + annotation.address() + annotation.name() + annotation.age() + Arrays.toString(annotation.hobbies()));
        Person person = new Person();
        person.setAddress(annotation.address());
        person.setAge(annotation.age());
        person.setName(annotation.name());
        person.setHobbies(annotation.hobbies()[0]);
        // 执行方法
        method.invoke(new PersonService(), person);
    }
}

引用:

https://www.jianshu.com/p/faf79ece1d88

https://www.liaoxuefeng.com/wiki/1252599548343744/1265102413966176

标签:Class,String,自定义,class,person,注解,annotation
来源: https://www.cnblogs.com/Andrew-Zhou/p/16436068.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有