目录

Annotation(注解)

meta-annotation(元注解)

@Target注解

@Retention注解

@Documented注解

@Inherited注解

注解应用举例


Annotation(注解)

从JDK 1.5开始, Java增加了对元数据(MetaData)的支持,也就是 Annotation(注解)。

注解其实就是代码里的特殊标记,它用于替代配置文件:传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行。在Java技术里注解的典型应用是:可以通过反射技术去得到类里面的注解,以决定怎么去运行类。

注解可以标记在包、类、属性、方法,方法参数以及局部变量上,且同一个地方可以同时标记多个注解。

// 抑制编译期的未指定泛型、未使用和过时警告
@SuppressWarnings({ "rawtypes", "unused", "deprecation" })
// 重写
@Override

meta-annotation(元注解)

除了直接使用JDK 定义好的注解,我们还可以自定义注解,在JDK 1.5中提供了4个标准的用来对注解类型进行注解的注解类,我们称之为 meta-annotation(元注解),他们分别是:

  • @Target

  • @Retention

  • @Documented

  • @Inherited

我们可以使用这4个元注解来对我们自定义的注解类型进行注解,接下来,我们挨个对这4个元注解的作用进行介绍。

@Target注解

Target注解的作用是:描述注解的使用范围(即:被修饰的注解可以用在什么地方) 。

Target注解用来说明那些被它所注解的注解类可修饰的对象范围:注解可以用于修饰 packages、types(类、接口、枚举、注解类)、类成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数),在定义注解类时使用了@Target 能够更加清晰的知道它能够被用来修饰哪些对象,它的取值范围定义在ElementType 枚举中。

public enum ElementType {TYPE, // 类、接口、枚举类FIELD, // 成员变量(包括:枚举常量)METHOD, // 成员方法PARAMETER, // 方法参数CONSTRUCTOR, // 构造方法LOCAL_VARIABLE, // 局部变量ANNOTATION_TYPE, // 注解类PACKAGE, // 可用于修饰:包TYPE_PARAMETER, // 类型参数,JDK 1.8 新增TYPE_USE // 使用类型的任何地方,JDK 1.8 新增}

@Retention注解

Reteniton注解的作用是:描述注解保留的时间范围(即:被描述的注解在它所修饰的类中可以被保留到何时) 。

Reteniton注解用来限定那些被它所注解的注解类在注解到其他类上以后,可被保留到何时,一共有三种策略,定义在RetentionPolicy枚举中。

public enum RetentionPolicy {SOURCE,    // 源文件保留CLASS,       // 编译期保留,默认值RUNTIME   // 运行期保留,可通过反射去获取注解信息
}

为了验证应用了这三种策略的注解类有何区别,分别使用三种策略各定义一个注解类做测试。

@Retention(RetentionPolicy.SOURCE)
public @interface SourcePolicy {}
@Retention(RetentionPolicy.CLASS)
public @interface ClassPolicy {}
@Retention(RetentionPolicy.RUNTIME)
public @interface RuntimePolicy {}

用定义好的三个注解类分别去注解一个方法。

public class RetentionTest {@SourcePolicypublic void sourcePolicy() {}@ClassPolicypublic void classPolicy() {}@RuntimePolicypublic void runtimePolicy() {}
}

如图所示,通过执行 javap -verbose RetentionTest命令获取到的RetentionTest 的 class 字节码内容如下。

{public retention.RetentionTest();flags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 3: 0public void sourcePolicy();flags: ACC_PUBLICCode:stack=0, locals=1, args_size=10: returnLineNumberTable:line 7: 0public void classPolicy();flags: ACC_PUBLICCode:stack=0, locals=1, args_size=10: returnLineNumberTable:line 11: 0RuntimeInvisibleAnnotations:0: #11()public void runtimePolicy();flags: ACC_PUBLICCode:stack=0, locals=1, args_size=10: returnLineNumberTable:line 15: 0RuntimeVisibleAnnotations:0: #14()
}

从 RetentionTest 的字节码内容我们可以得出以下两点结论:
           1. 编译器并没有记录下 sourcePolicy() 方法的注解信息; 
           2. 编译器分别使用了 RuntimeInvisibleAnnotations 和 RuntimeVisibleAnnotations 属性去记录了classPolicy()方法 和 runtimePolicy()方法 的注解信息;

@Documented注解

Documented注解的作用是:描述在使用 javadoc 工具为类生成帮助文档时是否要保留其注解信息。

为了验证Documented注解的作用到底是什么,我们创建一个带有 @Documented 的自定义注解类。

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;@Documented
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyDocumentedtAnnotation {public String value() default "这是@Documented注解为文档添加的注释";
}

再创建一个 MyDocumentedTest 类。

@MyDocumentedtAnnotation
public class MyDocumentedTest {@Override@MyDocumentedtAnnotationpublic String toString() {return this.toString();}
}

接下来,使用以下命令为 MyDocumentedTest 类生成帮助文档。

命令执行完成之后,会在当前目录下生成一个 doc 文件夹,其内包含以下文件。

查看 index.html 帮助文档,可以发现在类和方法上都保留了 MyDocumentedtAnnotation 注解信息。

修改 MyDocumentedtAnnotation 注解类,去掉上面的 @Documented 注解。

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyDocumentedtAnnotation {public String value() default "这是@Documented注解为文档添加的注释";
}

重新生成帮助文档,此时类和方法上的 MyDocumentedtAnnotation 注解信息都不见了。

@Inherited注解

Inherited注解的作用是:使被它修饰的注解具有继承性(如果某个类使用了被@Inherited修饰的注解,则其子类将自动具有该注解)。

接下来我们使用代码来进行测试,首先创建一个被@Inherited修饰的注解类MyInheritedAnnotation。

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyInheritedAnnotation {public String name() default "pengjunlee";
}

创建一个带有 MyInheritedAnnotation 注解的父类和一个无任何注解的子类。

@MyInheritedAnnotation(name="parent")
public class Parent {}
public class Child extends Parent{public static void main(String[] args) {Class<Child> child=Child.class;MyInheritedAnnotation annotation = child.getAnnotation(MyInheritedAnnotation.class);System.out.println(annotation.name());}
}

运行程序,打印结果如下:

parent

注解应用举例

首先自定义一个注解类。

package com.pengjunlee;import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MyAnnotation {public String name() default "pengjunlee";
}

在 AnnotationTest 中使用反射获取注解信息。

package com.pengjunlee;import java.lang.annotation.Annotation;
import java.lang.reflect.Method;@MyAnnotation(name = "name of type")
public class AnnotationTest {@MyAnnotation(name = "name of method")public String hello() {return "hello";}public static void main(String[] args) throws NoSuchMethodException, SecurityException {Class<AnnotationTest> annotationTest = AnnotationTest.class;// 获取类上的所有注解Annotation[] annotations = annotationTest.getAnnotations();for (Annotation annotation : annotations) {// 获取注解的全类名System.out.println(annotation.annotationType().getName());}// 获取 hello() 方法Method method = annotationTest.getMethod("hello", new Class[] {});// hello() 方法上是否有 MyAnnotation 注解if (method.isAnnotationPresent(MyAnnotation.class)) {// 获得注解MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);// 获取注解的内容System.out.println(annotation.name());}}
}

运行程序,打印结果如下:

com.pengjunlee.MyAnnotation
name of method

JAVA核心知识点--元注解详解相关推荐

  1. Java核心知识点之注解简介和最佳实践

    Java注解简介 Annotation 中文译过来就是注解.标释的意思,在 Java 中注解是一个很重要的知识点,但经常还是有点让新手不容易理解. 我个人认为,比较糟糕的技术文档主要特征之一就是:用专 ...

  2. Go语言核心知识点和原理详解

    go核心原理 本人在一家go技术栈工作2年有余,因此梳理一下我认为比较重要的go语言技术知识,一些基础的概念,比如function, interface这些就忽略了. https://dravenes ...

  3. Java基础13:反射与注解详解

    Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Orac ...

  4. java method 注解_JAVA 注解详解及简单实例

    JAVA 注解详解及简单实例 何为注解 注解(Annotation)又称为元数据,在JDK1.5后引入,它的作用是: 生成文档  这是注解的原始用途,可以通过注解生成JavaDoc文档 跟踪代码的依赖 ...

  5. Java开发常见面试题详解(LockSupport,AQS,Spring循环依赖,Redis)_3

    Java开发常见面试题详解(LockSupport,AQS,Spring循环依赖,Redis)_3 总览 问题 详解 String.intern()的作用 link LeetCode的Two Sum题 ...

  6. Java 1.8 函数式编程详解

    Java 1.8 函数式编程详解 文章目录 Java 1.8 函数式编程详解 一. 概述 1.1 java 8 新特性: 二. 函数式接口 2.1 函数式接口概述 2.2 Lambda表达式概述 2. ...

  7. java获取当前日期的前一天日期,Java核心知识点

    一.分布式架构学习路线图 据统计,人的阅读时间在20分钟以内是能够达到全身心投入的,顾文章单张篇幅以后会尽量缩短,但更新会尽量相应频繁一些. 二.计算机软件发展历史 首先我们了解下计算机软件的发展历史 ...

  8. mybatis注解详解

    mybatis注解详解 首 先当然得下载mybatis-3.0.5.jar和mybatis-spring-1.0.1.jar两个JAR包,并放在WEB-INF的lib目录下 (如果你使用maven,则 ...

  9. Spring零配置之@Configuration注解详解

    转载自 Spring零配置之@Configuration注解详解 @Configuration介绍 Spring3.0之前要使用Spring必须要有一个xml配置文件,这也是Spring的核心文件,而 ...

  10. java 配置文件的路径_详解java配置文件的路径问题

    详解java配置文件的路径问题 详解java配置文件的路径问题 各种语言都有自己所支持的配置文件,配置文件中有很多变量是经常改变的.不将程序中的各种变量写死,这样能更方便地脱离程序本身去修改相关变量设 ...

最新文章

  1. LeetCode Algorithm 242. 有效的字母异位词
  2. Vue 前端导出后端返回的excel文件
  3. left join on用法_MySQL 多表查询 quot;Joinquot;+“case when”语句总结
  4. Rust中Turbofish之函数后面双冒号(::)用法
  5. QT控件出现乱码问题
  6. SAP License:GL显示行项目
  7. Excel VBA 高级编程-工资条模板考勤工资管理系统
  8. spring boot动力电池数据管理系统毕业设计源码301559
  9. 网络安全应急响应-恶意代码分析技术
  10. Python爬虫教程:包图网免费付费素材爬取【附源码】
  11. 用python写问答机器人_机器人之Python入门到实践-问答机器人
  12. wcdma码片速率_码片速率 解释
  13. 读书笔记:专为中国人写的记忆书-数字密码表
  14. 神经网络 语音识别,神经网络语音合成
  15. WIN中SCHTASKS用法(定时执行程序)
  16. 怎么在腾讯云函数抖音无水印解析接口部署
  17. TCP/IP五层模型介绍
  18. 车载、行车记录仪产品知识汇集
  19. 英语论文格式修改(两栏)
  20. Java之Thread.sleep()浅析

热门文章

  1. 前端工作日记day2
  2. 人工智能技术在电气自动化中的应用,主要有哪些?
  3. oppo手机linux模式,OPPO工程模式怎么进 OPPO手机指令有哪些
  4. redis搭建哨兵模式(哨兵模式原理)
  5. java pointer_Java EE 8 JSON Pointer讲解
  6. 服务器证书有问题苹果手机,iPhone应用程序中的“服务器证书不可信”错误
  7. 程序员在哪能接到私单?
  8. 新年贺卡php,PS设计2016猴年大吉新年贺卡
  9. 不积跬步无以至千里,反思
  10. java append()_append()方法的坑