Java注解的学习之元注解说明

29次阅读

共计 2252 个字符,预计需要花费 6 分钟才能阅读完成。

最近在学习 Spring Boot,发现真的是一个靠注解搭起来的框架,Spring 从使用 XML 到现在使用注解,大概是终于发现绝大多数人所写的项目,都不需要 XML 的松耦合,快速上线、快速丢弃、快速接手,在一切都要求快的互联网公司里,XML 这样的松耦合浪费太多的学习成本了,划不来。

之前一直没有系统学习过 Java 的注解,学习起 Spring Boot 来总是用得不明所以,想想还是从基础学起,方不至于浪费大量的时间去查找 Spring Boot 各个注解的使用文档。

Java 的注解,实际上包含三方面的内容,一个是 Java 注解本身的定义,一个是 Java 注解的使用,一个是如何利用 Java 的反射功能实现功效。本文也将从这三个方面逐一讲解,主要参考文章 JAVA 注解的基本原理 和 Java 语法标准。

Java 内置了许多的注解,在 Java Annotation 可以找到内置的所有注解,我们最常见的注解应该是 @Deprecated,一旦一个方法使用了这个注解,别人此后再使用这个方法时,就会提示这个方法已经被废弃了,建议不再使用。

那 @Deprecated 到底是怎么定义的呢?它还能用在什么地方?JDK 是如何在编译的时候遇到这个注解就马上发出一个提示的呢?带着这些疑问,一步一步学习 Java 的注解。

一、如何创建一个注解

所有的注解本身都继承于 java.lang.annotation.Annotation, 每一个注解本身就是一个 interface,但是注解这种 interface 有其特殊性,所以,所有的注解都是这样定义的:

publice @interface xxxx {}

@Deprecated 的实现代码如下:

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

多了 @Documented,@Retention,@Target 三个注解,这三个注解分别是什么呢?又有什么作用呢?

用于方法的方法,叫做元方法,所以用于注解的注解,就叫做元注解,这三个都是 JDK 提供的元注解。

  1. @Documented 标记这个注解 @Deprecated 将会出现在 Java Doc 之中
  2. @Rentention 标明这个注解的生命周期,RententionPolicy 里面定义了三种生命周期,分别是 SOURCE,CLASS,RUNTIME 三种,SOURCE 表示在编译阶段抛弃,CLASS 表示会被记录到 class 文件里面,但不会出现在 vm 里面运行,RUNTIME 表示在运行期里面存活。
  3. @Target 表示这个注解可以用在何处,比如 @Deprecated 的定义,表明它可以用在构造函数,字段,本地变量,方法,包,参数,类
@Deprecated
public class TestDeprecated {
    @Deprecated
    public String name;

    @Deprecated
    public TestDeprecated(String name){ }

    @Deprecated
    public String getName() {return name;}

    public void testDeprecatedParam(@Deprecated String name, String sex){
        @Deprecated
        String test = "test";
        System.out.println(name + sex + test);
    }
}

如上是 @Deprecated 在类、字段、构造函数、方法、参数和本地变量的使用方式。不过本地变量和参数的 @Deprecated 似乎是不起作用的。另外,package 级别的注解使用,需要使用 package-info.java, 比如 package-info.java 文件如下:

@Deprecated
package com.shahuwang;

这样子就标记了整个包都是要废弃的了。

目前 Java 10 提供了 @Documented,@Inherited,@Native,@Repeatable,@Retention,@Target 共六个元注解,除了上面已讲解过的三个,剩余三个的用途:

  1. @Inherited 表示使用了它的注解,再用到类上面时,可被子类继承此注解。

       @Inherited
       publice @interface Test{}
       
       @Test  
       public class Parent{}
       
       public class Child extends Parent{}
       

    如上,Child 类也继承了 @Test 这个注解,可以使用它的功能。

  2. @Native 表示定义常量值的字段可以被 native 代码引用,当 native 代码和 java 代码都需要维护相同的常量时,如果 java 代码使用了 @Native 标志常量字段,可以通过工具将它生成 native 代码的头文件。目前对 Java 的 native 代码研究比较少,后面再对它进行研究
  3. @Repeatable 表示注解可以重复使用,是 Java 8 引进的特性。之前注解只能在同一个地方用一次,用了 @Repeatable,注解就可以在同一个地方使用多次了,可以参考这篇文章 https://blog.csdn.net/aitangy…

正文完
 0