• Java 注解


    简介

    注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释代码本身的一部分。注解对于代码的运行效果没有直接影响。

    主要作用

    • 提供信息给编译器: 编译器可以利用注解来探测错误和警告信息
    • 编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。
    • 运行时的处理: 某些注解可以在程序运行的时候接受代码的提取

    定义

    注解和类、接口等是一个层次的东西,它的声明是用@interface标识的,跟接口很像,如下所示:

    public @interface Zeling {
    }
    

    元注解-注解的注解

    @Documented

    使用这个注解,可以让注解中的元素包含到javadoc或者类似的工具上去。

    // Indicates that annotations with a type are to be documented by javadoc and similar tools by default.

    @Target

    限定运用场景,可以同时限定多个,比如说新定义一个注解,限定在类型和方法注解。

    // Indicates the contexts in which an annotation type is applicable.

    主要有以下几种:

        // 限定给类型注解,比如说类、接口、枚举等
        TYPE,
    
        // 限定给属性注解
        FIELD,
    
        // 限定给方法注解
        METHOD,
    
        // 限定给参数注解
        PARAMETER,
    
        // 限定给构造函数注解
        CONSTRUCTOR,
    
        // 限定给局部变量注解
        LOCAL_VARIABLE,
    
        // 限定在注解上注解
        ANNOTATION_TYPE,
    
        // 限定在包上使用注解
        PACKAGE

    @Retention

    保留期,即注解可以在什么时间段上起作用。

    • SOURCE 源代码阶段起作用
    • CLASS 到编译阶段还能起作用
    • RUNTIME 到运行期还能起作用

    @Inherited

    继承注解:当一个超类使用了这个注解,然后他的子类如果没有使用注解的话,那么子类可以继承超类的注解。

    // 注解A
    public @interface A {}
    
    // 超类B
    @A
    public class B {}
    
    // B的子类C
    public class C extends B {}

    那么,C也拥有注解A。

    @Repeatable

    可重复的,当一个注解A使用了这个可重复的注解,那么注解A可以多次注解在同一个地方。

    public @interface Colors {
        Color[] value();
    }
    
    @Repeatable(Colors.class)
    public @interface Color {
        String color() default "black";
    }
    
    @Color("purple")
    @Color("brown")
    @Color("red")
    public class Pen {}

    上面这个代码块就是这个注解的习惯用法,自己理解哈。

    注解的属性

    注解只有属性,没有方法。注解的属性定义跟无形参的方法很像。

    public @interface A {
        // String 是属性的返回值,msg是属性的名称,可以用default后面跟着默认的值
        String msg() default "msg";
    }

    使用方式

    @A(msg = "zeling")
    public class B {}

    如果注解属性中,只有一个属性,并且属性的名称为value那么可以直接在注解后面直接填值,不用写出属性名,如:

    @C(value = "msg")
    //等价于
    @C("msg")

    注解的运用

    Class中有三个为注解提供的方法:

    // 判断是否使用了注解
    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}
    // 获取某个注解
    public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}
    // 获取所有注解
    public Annotation[] getAnnotations() {}
    

    例子:

    @Zeling(msg = "zeling")
    public class App {
        /**
         * @description TODO
         * @date 2018年1月31日 下午11:06:13
         * @param args
         */
        public static void main(String[] args) throws Exception {
            boolean flag = App.class.isAnnotationPresent(Zeling.class);
            if (flag) {
                Zeling zeling = App.class.getAnnotation(Zeling.class);
                System.out.println("annotation: " + zeling.msg());
            }
    
        }
    }

    结果:

    annotation: zeling

    PS:记得给注解Zeling的作用时段设置为RetentionPolicy.RUNTIME哦,不然你可看不到输出的。还有就是,注解的提取是基于反射机制的,而反射是比较耗时的,所以使用注解的时候请考虑时间成本。

    结语

    错误之处还请帮忙指正~

  • 相关阅读:
    Hibernate学习笔记_关系映射
    Hibernate学习笔记_核心幵发接口及三种对象状态
    Hibernate学习笔记_联合主键
    Hibernate学习笔记_ID生成策略
    API的控制器
    MVC跨域API
    WindowsForms 调用API
    触发器
    视图
    分页的存储过程的用法
  • 原文地址:https://www.cnblogs.com/zeling/p/8494839.html
Copyright © 2020-2023  润新知