转载

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

最近在学习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...
原文  https://segmentfault.com/a/1190000019936605
正文到此结束
Loading...