• Java注解(Annotation)


    一、什么是注解

    个人理解,注解就是代码中的特殊标记,这些标记可以在编译、类加载、运行时被读取,从而做相对应的处理

    注解跟注释很像,区别是注释是给人看的;而注解是给程序看的,它可以被编译器读取

    二、注解的作用

    注解大多时候与反射或者 AOP 切面结合使用,它的作用有很多,比如标记和检查,最重要的一点就是简化代码,降低耦合性,提高执行效率。比如可以通过自定义注解 + AOP 切面结合,解决写接口重复提交的问题。

    三、注解的定义语法

    1. // 声明 NoRepeatSubmit 注解
    2. @Target(ElementType.METHOD) // 元注解
    3. @Retention(RetentionPolicy.RUNTIME) // 元注解
    4. public @interface MyAnnotation {
    5. /**
    6. * 锁定时间,默认单位(秒)
    7. */
    8. long lockTime() default 3L;
    9. }

    四、注解类型

    注解可以分为三类,基本注解、元注解和自定义注解

    其中基本注解例如@Override 用于表明检查方法是否被重写;@SuppressWarning 表明编译器忽略注解中声明的警告。

    元注解常用的@ Retention用来定义该注解在哪一个级别可用,在源代码中(SOURCE)、类文件中(CLASS)或者运行时(RUNTIME);@Target:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)。

     自定义注解则可以根据第三部分语法自己定义需要的注解。

    五、代码演示

     首先声明一个注解,Init用来表示这个方法是初始化方法。

    1. import java.lang.annotation.*;
    2. @Target(ElementType.METHOD)
    3. @Retention(RetentionPolicy.RUNTIME)
    4. public @interface Init {
    5. }

    再写一个Demo类,写几个方法并用Init注解,表明这些类会在类初始化时候使用。 Demo类中有两个构造方法,有两个被@Init修饰的方法。

    1. package Annotation;
    2. public class Demo {
    3. int i;
    4. int l;
    5. public Demo(){
    6. System.out.println("无参构造方法");
    7. }
    8. public Demo(int i,int l ){
    9. this.i = i;
    10. this.l = l;
    11. System.out.println("有参构造方法"+this.i+this.l);
    12. }
    13. @Init
    14. public void print(){
    15. System.out.println("无参初始化方法");
    16. }
    17. @Init
    18. public void printInt(int i){
    19. System.out.println("有参初始化方法"+i);
    20. }
    21. }

    定义一个测试类用来通过反射来获取被@Init修饰的方法,并操作方法

    1. import java.lang.reflect.Method;
    2. public class Test {
    3. public static void main(String[] args) throws Exception {
    4. Classextends Demo> aClass = Demo.class;
    5. //有参建立实例
    6. Demo demo = aClass.getConstructor(int.class, int.class).newInstance(6, 7);
    7. //无参数建立实例
    8. //1、
    9. aClass.newInstance();
    10. //2、
    11. aClass.getConstructor(null).newInstance(null);
    12. System.out.println("-----------------------------");
    13. //不含构造方法父类继承方法
    14. Method[] declaredMethods = aClass.getDeclaredMethods();
    15. for (Method declaredMethod : declaredMethods) {
    16. //判断方法是否存在Init
    17. boolean annotationPresent = declaredMethod.isAnnotationPresent(Init.class);
    18. //如果存在则调用
    19. if(annotationPresent){
    20. if(declaredMethod.getName().equals("printInt")){
    21. declaredMethod.invoke(aClass.getConstructor(null).newInstance(null),5);
    22. }
    23. else {
    24. declaredMethod.invoke(aClass.getConstructor(null).newInstance(null));
    25. }
    26. }
    27. }
    28. }
    29. }

    运行结果:

    1. 有参构造方法67
    2. 无参构造方法
    3. 无参构造方法
    4. -----------------------------
    5. 无参构造方法
    6. 无参初始化方法
    7. 无参构造方法
    8. 有参初始化方法5

    这里有一个小的知识点,newInstance()创建实例的两种方法

    Class.newInstance()
    Constructor(Classes).newInstance(args)

    以下对两种调用方式给以比较说明:
    Class.newInstance() 只能够调用无参的构造函数,即默认的构造函数;
    Constructor.newInstance() 可以根据传入的参数,调用任意构造构造函数。

    Class.newInstance() 抛出所有由被调用构造函数抛出的异常。

    Class.newInstance() 要求被调用的构造函数是可见的,也即必须是public类型的;
    Constructor.newInstance() 在特定的情况下,可以调用私有的构造函数。

  • 相关阅读:
    力扣739:每日温度 (Java多种方法)
    【C++】模板进阶
    go中的panic defer recover
    C++哪些函数不能成为虚函数
    BeanUtils.copyProperties的用法
    CSPM是否可以申请职称?解答来了
    SwiftUI SQLite 教程之 构建App本地数据库实现创建、读取、更新和删除(教程含完成项目源码)
    平时整理的一些小算法
    【JVM笔记】方法区的内部结构与运行时常量池
    随想录一刷Day44——动态规划
  • 原文地址:https://blog.csdn.net/ANobility/article/details/128095052