• 注解详解


    一:注解的作用

    注解是jdk5引入的新特性,注解相当于增加了一个配置,当我们使用注解时,我们可以通过反射获取注解从而获取相关的配置,方便我们在代码层面做一些操作。

    二:注解的相关概念以及使用

    注解的分类:   

    • 供javadoc生成文档用的注解。@param @return 等。
    • 自定义注解,相当于配置文件的作用,使用灵活,配置简单。
    • 在编译时进行格式检查。@override检查是否重写了父类方法。@SuppressWarnings抑制编译器产生的警告信息。@Deprecated标记过时的方法等不推荐再使用。

      包 java.lang.annotation 中包含所有定义自定义注解所需用到的元注解和接口。所有注解默认继承了java.lang.annotation.Annotation接口。

    注解中概念:

    自定义注解时使用了四个元注解,就是用于注解的注解。四个元注解分别是:@Target,@Retention,@Documented,@Inherited。

    @Target定义注解作用的地方。可以是类、方法、属性等。常用的值由一个枚举类定义:ElementType。

    ElementType.FIELD,//作用在属性上
    ElementType.METHOD,//作用在方法上
    ElementType.CONSTRUCTOR,//作用在构造函数上
    ElementType.LOCAL_VARIABLE,//作用在本地变量上
    ElementType.PACKAGE,//作用在包上
    ElementType.PARAMETER,//作用在方法参数上
    ElementType.TYPE//作用在类,接口,枚举类等

    @Retention定义了注解的生命周期,即注解在什么范围内有效。

    • SOURCE:在源文件中有效
    • CLASS:在class文件中有效
    • RUNTIME:在运行时有效(即运行时保留,我们自定义的注解一般是要在运行时使用的)

    @Documented 表示此注解作用的内容会被javadoc工具提取到文档中。

    @Inherited表示该注解会被继承。使用该元注解的自定义注解一般作用范围是ElementType.TYPE,如果是作用在ElementType.METHOD的注解,在子类重写了使用注解的方法的时候,此时子类重载方法是没有继承该注解的,不重写方法则子类可以获取继承的注解。

    自定义注解的方式:

    使用@interface来定义一个自定义注解,使用方法定义自定义注解中的属性,方法的返回值定义属性值的类型。

    注解使用案例一:

    注解定义:

          

    @Target({ElementType.FIELD,ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface DatasourceAnnotation {
        String datasourceName();
        int sequence();
    }

    注解使用:

    public class UserService {
        @DatasourceAnnotation(datasourceName = "master", sequence = 1)
        public String datasourceName;
    
        @DatasourceAnnotation(datasourceName = "salve", sequence = 2)
        public String selectUserNameById(Integer id) {
            return "test";
        }
    }
    public class AnnotationTest {
        private void handleFieldAnnotation() throws NoSuchFieldException {
            Field datasourceName = UserService.class.getField("datasourceName");//获取属性
            if (datasourceName.isAnnotationPresent(DatasourceAnnotation.class)) {//判断属性上有无此注解
                DatasourceAnnotation annotation = datasourceName.getAnnotation(DatasourceAnnotation.class);//获取注解
                System.out.println(annotation.datasourceName());
                System.out.println(annotation.sequence());
            }
        }
    
        private void handleMethodAnnotation() throws NoSuchMethodException {
            Method selectUserNameById = UserService.class.getMethod("selectUserNameById", Integer.class);
            if (selectUserNameById.isAnnotationPresent(DatasourceAnnotation.class)) {
                DatasourceAnnotation annotation = selectUserNameById.getAnnotation(DatasourceAnnotation.class);
                System.out.println(annotation.datasourceName());
                System.out.println(annotation.sequence());
            }
        }
    
    
        @Test
        public void test() throws Exception {
            handleFieldAnnotation();
            handleMethodAnnotation();
        }
    }

    运行结果:

    master
    1
    salve
    2
    
    Process finished with exit code 0

    注解使用案例二:继承注解(作用在ElementType.METHOD上 子类的重写方法是无法继承注解的,不重写方法子类是可以获取注解的

    注解定义:

    @Target({ElementType.TYPE,ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    public @interface InheritedAnnotation {
        String name();
    }

    注解使用:

    @InheritedAnnotation(name = "test")
    public class UseInheritedAnnotation {
    }
    public class SubUseInheritedAnnotation extends UseInheritedAnnotation{
    }
    @Test
        public void test() throws Exception {
            InheritedAnnotation annotation = SubUseInheritedAnnotation.class.getAnnotation(InheritedAnnotation.class);
            System.out.println(annotation.name());
        }

    运行结果:

    test
    
    Process finished with exit code 0

    作用在ElementType.METHOD上 子类的重写方法是无法继承注解的,不重写方法子类是可以获取注解的

    public class UseInheritedAnnotation {
        @InheritedAnnotation(name = "methodTest")
        public String test(){
            return "";
        }
    }
    public class SubUseInheritedAnnotation extends UseInheritedAnnotation{
        @Override
        public String test(){
            return "";
        }
    }
    @Test
        public void test() throws Exception {
            Method test = SubUseInheritedAnnotation.class.getMethod("test", null);
            InheritedAnnotation annotation = test.getAnnotation(InheritedAnnotation.class);
           
            System.out.println(annotation.name());
        }

    运行结果:

    java.lang.NullPointerException
        at com.ctj.annotationTest.AnnotationTest.test(AnnotationTest.java:35)

    三:使用注解的过程中的注意事项

  • 相关阅读:
    jQuery EasyUI介绍
    CodeMirror:基于JavaScript的代码编辑器
    概述:分布式文件系统+分布式存储+分布式处理
    HTML学习笔记——标准网页设计+使用CSS、Javascript
    HTML学习笔记——常用元素及其属性(二)
    HTML学习笔记——常用元素及其属性(一)
    Remmarguts' Date(k短路问题)
    K短路问题模板(spfa+A*)
    树状数组求逆序对模板
    桐桐的糖果计划(tarjan求桥+双连通分量)
  • 原文地址:https://www.cnblogs.com/programmer1/p/8946242.html
Copyright © 2020-2023  润新知