• Java注解一张图一案例掌握自定义注解


    1.概述

    是什么:是对方法、类、参数、包、域以及变量等进行代码功能的增强或者修改程序的行为等操作。

    应用

    • 跟踪代码依赖性,实现替代配置文件功能
    • 在反射中使用Annotation,字段格式化(如:数据字段脱敏、日期格式)
    • 在编译时进行格式检查
    • 生成帮助文档

    2.注解相关知识

    元注解指的是所有注解都基于它们而产生的最基础的注解。

    2.1.Annotation接口和元注解

    这张图包含了Annotation接口信息、4个元注解作用和元注解的参数信息

    image

    整体关系(具体信息都在图中)

    • 顶级注解接口:Annotation

    • 元注解

      • @Documented
      • @Inherited
      • @Target
      • @Retention
    • native级别的关键字

      • @interface 指明是注解类

    关联关系

    • 1个Annotation 和 1个RetentionPolicy关联。

      • 可以理解为:每1个Annotation对象,都会有唯一的RetentionPolicy属性。
    • 1个Annotation 和 1~n个ElementType关联。

      • 可以理解为:对于每1个Annotation对象,可以有若干个ElementType属性。

    2.2.注解元素支持的数据类型

    • 所有基本类型
    • String
    • Class
    • enum
    • annotation
    • 以上类型的数组

    2.3.常见基础注解的作用

    @SuppressWarnings:抑制编译器警告的注解,编译检查注解

    @Deprecated:弃用注解,编译检查注解

    @Override:限定重写父类方法的注解,具有编译检查作用

    @FunctionalInterface:函数式接口注解,限制接口只能有一个抽象方法

    3.自定义注解

    返回值类型等于参数的类型,

    方法的名称等于参数的名称(使用注解是参数名称),

    可以通过default关键字来声明参数的默认值。

    通过一个案例来理解注解的使用(不懂反射的可以看我的另一篇文章)

    3.1.案例:通过反射处理自定义注解

    自定义注解类:颜色注解类 + 颜色枚举

    @Target( ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ColorBanana {
        /**
         * 颜色枚举类
         */
        public enum Color{
            YELLOW,
            BLACK,
            WHITE,
            RED
        }
        // 颜色属性
        Color colorBanana() default Color.YELLOW;
    
    }
    

    实体类:使用注解的类

    public class Banana {
    
        private String bananaName;
        @ColorBanana(colorBanana = ColorBanana.Color.RED)
        private String bananaColor;
    
        public String getBananaName() {
            return bananaName;
        }
    
        public void setBananaName(String bananaName) {
            this.bananaName = bananaName;
        }
    
        public String getBananaColor() {
            return bananaColor;
        }
    
        public void setBananaColor(String bananaColor) {
            this.bananaColor = bananaColor;
        }
        @Override
        public String toString() {
            return "Banana{" + "bananaName=" + bananaName + ", bananaColor=" + bananaColor + "}";
        }
    }
    

    测试类:反射处理注解

    public class BananaTest {
    
        // 创建注解赋值后的Banana实例对象
        public static Banana newBanana() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
            Class<Banana> bananaClass = Banana.class;
            Banana banana = bananaClass.getConstructor().newInstance();
            /**
             * 获取Banana类中 ColorBanana注解信息
             *   因为注解信息打在成员变量上,所以要通过Filed来get注解
             *   (注解打在什么上,就用什么来获取注解)
             */
            Field[] fields = bananaClass.getDeclaredFields();//注解打在私有成员变量,所以要用getDeclaredFields
            for (Field field : fields){
                field.setAccessible(true);//忽略私有修饰符得限制,否则报语法错误
                // 拿到注解
                ColorBanana annotation = field.getAnnotation(ColorBanana.class);
                // 有些字段没有ColorBanana注解,记得判空
                if (annotation != null){
                    ColorBanana.Color color = annotation.colorBanana();
                    System.out.println("输出注解中得信息:"+field.getName()+"="+color);
                    /*
                     * 将注解中得信息赋值到对象对应字段中
                     *   因为实体类Banana 的bananaColor字段是字符串,所以要拿枚举类属性得name(名称)进行赋值
                     */
                    field.set(banana,color.name());
                }
            }
            // 输出反射得到得对象信息
            System.out.println(banana);
            return banana;
        }
    
        public static void main(String[] args) throws Exception {
            Banana banana = newBanana();
            banana.setBananaName("myBananaName");
            System.out.println(banana);
        }
    }
    

    执行结果:

    输出注解中得信息:bananaColor=RED

    Banana{bananaName=null, bananaColor=RED}

    Banana{bananaName=myBananaName, bananaColor=RED}

    注解值成功传入到实例化对象中的对应字段,并返回实例化对象给调用者。

    image

    Java往期文章

    Java全栈学习路线、学习资源和面试题一条龙

    我心里优秀架构师是怎样的?

    免费下载经典编程书籍

    image

    原创不易,三联支持:点赞、在看、分享

  • 相关阅读:
    System.out.println与System.err.println的区别
    数组及引用类型内存分配
    数组及引用类型内存分配
    JAVA内存分配-通俗讲解
    JAVA内存分配-通俗讲解
    java中abstract怎么使用
    MyEclipse 快捷键
    SQLite -创建表
    配置Hexo
    Dykin's blog
  • 原文地址:https://www.cnblogs.com/dennyLee2025/p/16056724.html
Copyright © 2020-2023  润新知