• 再论Java注解


    一、什么是注解?

    注解其实就是代码中的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相对应的处理

    二、为什么要用注解开发?

    传统的方式是,通过配置文件(xml文件 )来告诉类是如何运行的,使用注解开发后,通过注解告诉类是如何运行

    三、元注解(注解的注解)

    • @Target:注解作用目标(即:被描述的注解可以用在什么地方)

      • @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)——包
    • @Retention:注解的保留位置,用于描述注解的生命周期(SOURCE->CLASS -> RUNTIME

      • RetentionPolicy.SOURCE:这种类型的Annotations只在源代码级别保留,编译时就会被忽略,在class字节码文件中不包含
      • RetentionPolicy.CLASS:这种类型的Annotations编译时被保留,默认的保留策略,在class文件中存在,但JVM将会忽略,运行时无法获得
      • RetentionPolicy.RUNTIME:这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。
    • @Document:说明该注解将被包含在javadoc

    • @Inherited:是一个标识,用来修饰注解

      • 作用:如果一个类用上了@Inherited修饰的注解,那么其子类也会继承这个注解

        注意:

        • 接口用上个@Inherited修饰的注解,其实现类不会继承这个注解
        • 父类的方法用了@Inherited修饰的注解,子类也不会继承这个注解

    四、JDK基本注解

    4.1 @Override

    重写注解

    @Overried是告诉编译器要检查该方法是实现父类的…可以帮我们避免一些低级的错误…

    比如,我们在实现equals()方法的时候,把euqals()打错了,那么编译器就会发现该方法并不是实现父类的,与注解@Override冲突,于是就会给予错误

    4.2 @Deprecated

    过时注解

    在Java迭代中,觉得某些方法设计不好,而为了兼容老版本,不能直接抛弃掉,于是加上注解表明过时的,不建议再用

    Date对象中的toLocalString()就被设计为过时的

    @Deprecated
    public String toLocaleString() {
        DateFormat formatter = DateFormat.getDateTimeInstance();
        return formatter.format(this);
    }
    

    4.3 SuppressWarnings

    镇压警告注解

    该注解可以抑制编译器给我们提示的安全警告

    4.4 @SafeVarargs

    Java7 “堆污染”警告注解

    在声明具有模糊类型(比如:泛型)的可变参数的构造函数或方法时,Java编译器会报unchecked警告。鉴于这些情况,如果程序员断定声明的构造函数和方法的主体不会对其varargs参数执行潜在的不安全的操作,可使用@SafeVarargs进行标记,这样的话,Java编译器就不会报unchecked警告

    4.5 @FunctionalInterface

    @FunctionalInterface函数式接口注解

    该注解指定该接口是函数式接口

    五、自定义注解

    需求:给方法或类注入信息

    5.1 标记Annotation

    没有任何成员变量的注解称作为标记注解,@Overried就是一个标记注解

    public @interface MyAnnotation {
    }
    

    5.2 元数据Annotation

    注解是可以带成员变量的,定义带成员变量的注解叫做元数据Annotation

    在注解中定义成员变量,语法类似于声明方法一样….

    public @interface MyAnnotation {
        String username();
        int age();
    }
    

    5.3 使用自定义注解

    5.3.1 基本使用

    给add方法注入username和age这 两个参数

    //注解拥有什么属性,在修饰的时候就要给出相对应的值
    @MyAnnotation(username = "xiaoming", age = 20)
    public void add(String username, int age) {
    }
    

    5.3.2 默认值

    注解声明属性的时候给出默认值,这样我们就可以在使用注解的时候省略掉属性赋值

    public @interface MyAnnotation {
        String username() default "xiaoming";
        int age() default 20;
    }
    

    使用注解

    @MyAnnotation()
    public void add(String username, int age) {
    }
    

    5.3.3 注解属性为value

    有一种特殊的情况,如果注解上只有一个属性,并且属性的名称为value,那么在使用的时候,我们可以不写value,直接赋值给它就行

    public @interface MyAnnotation2 {
       String value();
    }
    

    使用注解

    @MyAnnotation2("zhongfucheng")
    public void find(String id) {
    }
    

    六、总结

    1. 注入对象的步骤:得到想要注入的对象属性,通过属性得到注解的信息,通过属性的写方法将注解的信息注入到对象上,最后将对象赋给类

    2. 注解其实就是两个作用:

      1. 让编译器检查代码
      2. 将数据注入到方法、成员变量、类上
    3. 在JDK中注解分为

      1. 元Annotaion:在annotaion包下,常用于修饰其他的Annotation定义
      2. 基本Annotation:在lang包下,用于常用于标记该方法,抑制编译器警告等
  • 相关阅读:
    【每日更新】【Redis学习】
    【转】RabbitMQ基础——和——持久化机制
    【转】重写Equals为什么要同时重写GetHashCode
    .net WebApi中使用swagger生成WepApi集成测试工具
    【深度好文】多线程之WaitHandle-->派生EventWaitHandle事件构造-》AutoResetEvent、ManualResetEvent
    C#编码问题以及C#往Mysql插数据编码问题
    HTTP methods 与 RESTful API
    Facebook币Libra学习-6.发行属于自己的代币Token案例(含源码)
    Facebook币Libra学习-5.Move组织目录
    Facebook币Libra学习-4.新的智能合约语言Move入门
  • 原文地址:https://www.cnblogs.com/fm98/p/15568947.html
Copyright © 2020-2023  润新知