• java注解和通过反射获取注解值


    1.java自带的标准注解

    @Override @SuppressWarnings @Deprecated

    package com.lt.annotation;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * java自带的标准注解
     * 不写继承类时,会默认继承Object类
     */
    public class Test01 extends Object{
    
        /**
         * @Override:覆盖或实现在超类型中声明的方法,即重写
         * 即:该方法与超类的方法名、参数一致
         *      访问权限不能比父类中被重写的访问权限低
         *      返回值类型可以不同,但必须为父类返回值的派生类。
         * @return
         */
        @Override
        public String toString() {
            return super.toString();
        }
    
        /**
         * 镇压警告,可以加载方法上,也可以加载类上
         */
        @SuppressWarnings("all")
        public void test01(){
            List list = new ArrayList();
        }
    
        /**
         * 过时的,不推荐使用的方法加上该注解
         */
        @Deprecated
        public static void test02(){
            System.out.println("test……");
        }
        
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    2.元注解

    元注解:负责解释其他注解

    • @Target:用来限制注解的使用范围
    /**
     * 可以看到,Target的参数为一个数组,所以可以写多个值,且参数名有且只有vaule,声明该注解是参数名可以省略
     * 
     * @Target(ElementType.TYPE)——接口、类、枚举、注解
     * @Target(ElementType.FIELD)——字段、枚举的常量
     * @Target(ElementType.METHOD)——方法
     * @Target(ElementType.PARAMETER)——方法参数
     * @Target(ElementType.CONSTRUCTOR) ——构造函数
     * @Target(ElementType.LOCAL_VARIABLE)——局部变量
     * @Target(ElementType.ANNOTATION_TYPE)——注解
     * @Target(ElementType.PACKAGE)——包,用于记录java文件的package信息
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Target {
        ElementType[] value();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • @Retention:表示我们的注解在什么位置还有效(runtime > class > source),一般自定义注解都写runtime
    /**
     * @Retention:表示我们的注解在什么位置还有用
     * 可以看到参数类型是:RetentionPolicy
     * 看下源码,它是一个枚举类型,SOURCE CLASS RUNTIME
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Retention {
        RetentionPolicy value();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • @Document:表示是否将我们的注解生成在JavaDoc中
    • @Inherited:子类可以继承父类的注解
    • @Repeatable:该注解是Java8新增的注解,用于开发重复注解

    3.自定义一个简单注解

    /**
     * @Target:声明了该注解可以加到方法、接口、类、枚举、注解上
     * @Retention:声明了该注解在源码、字节码和运行时都有效
     * 
     * 声明了参数为:name,类型为String类型
     */
    @Target(value={ElementType.METHOD,ElementType.TYPE})
    @Retention(value= RetentionPolicy.RUNTIME)
    @interface MyAnnotation{
        String name();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4.定义一个注解并获取

    ①定义注解

    @Target(value = {ElementType.TYPE,ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @interface  MyAnnotationTest2{
        //注解的参数:参数类型  参数名();
        String name() default "默认值";
        int age() default 0;
        int id() default -1;//如果默认值为-1,代表不存在。
    
        String[] schools() default {"西部开源","清华大学"};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    ②使用注解

    /**
     * 自定义注解
     */
    @MyAnnotationTest2(name = "乐天")
    public class Test03 {
    
        @MyAnnotationTest2(name = "二狗儿",schools = {"南大"})
        public void test01(){
    
        }
        
    
        @MyAnnotationTest2(name = "鸡蛋儿",schools = {"北大"})
        public void test02(){
    
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    ③获取类上的注解的参数值

    /**
     * 获取类上的注解值
     */
    public class Test04 {
        public static void main(String[] args) {
            //获取该类的Class
            Class<Test03> test03Class = Test03.class;
            //判断该类上是否使用了MyAnnotationTest2注解
            boolean annotation = test03Class.isAnnotationPresent(MyAnnotationTest2.class);
            if(annotation){
                //通过Class获取该类上的注解
                MyAnnotationTest2 myAnnotationTest = test03Class.getAnnotation(MyAnnotationTest2.class);
                System.out.println("name:" + myAnnotationTest.name());
                System.out.println("age:" + myAnnotationTest.age());
                System.out.println("id:" + myAnnotationTest.id());
    
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    输出:

    name:乐天
    age:0
    id:-1
    
    
    • 1
    • 2
    • 3
    • 4

    ④获取方法上的注解的参数值

    /**
     * 获取方法上的注解值
     */
    class GetAnnoMethod{
        public static void main(String[] args) {
            Method[] declaredMethods = Test03.class.getDeclaredMethods();
            for (Method m : declaredMethods){
                if(m.isAnnotationPresent(MyAnnotationTest2.class)){
                    System.out.println("name:" + m.getAnnotation(MyAnnotationTest2.class).name());
                    System.out.println("age:" + m.getAnnotation(MyAnnotationTest2.class).age());
                    System.out.println("id:" + m.getAnnotation(MyAnnotationTest2.class).id());
                    System.out.println("school:" + Arrays.toString(m.getAnnotation(MyAnnotationTest2.class).schools()));
                    System.out.println("**********************************");
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    输出:

    name:二狗儿
    age:0
    id:-1
    school:[南大]
    **********************************
    name:鸡蛋儿
    age:0
    id:-1
    school:[北大]
    **********************************
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    SwiftUI 动态岛开发教程之什么是Dynamic Island,快速完整demo
    药事管理学考试试题及答案
    [数据分析与可视化] Python绘制数据地图2-GeoPandas地图可视化
    C访问数据对象在内存中的位模式
    YOLOV7实战(pycharm)-以口罩检测为例
    ubuntu联网图标消失
    AI对抗中的AI:技术展望与应用研究
    C#版字节跳动SDK - SKIT.FlurlHttpClient.ByteDance
    【Django下载文件-Kml文件下载】
    家政服务小程序,家政预约小程序,家政服务预约小程序源码
  • 原文地址:https://blog.csdn.net/weixin_44613100/article/details/125406053