文档章节

关于Java的Retention元注解

摆渡者
 摆渡者
发布于 2017/08/29 16:55
字数 736
阅读 524
收藏 0

Demo

写了一个自定义注解:

package com.my.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotation {
	String value();
}

定义了一个类A,并用MyAnnotation标注。测试类中:

package com.my.test;

@MyAnnotation("This is MyAnnotation. ^_^")
class A {}

public class Test {
	public static void main(String[] args) {
		MyAnnotation annotation = A.class.getAnnotation(MyAnnotation.class);
		if (annotation != null) {
			System.out.println(annotation.value());
		} else {
			System.out.println("No such annotation.");
		}
	}
}

执行结果:

No such annotation.

如果把MyAnnotation类的Retention改为RetentionPolicy.CLASS,结果还是No such annotation。

如果改为RetentionPolicy.RUNTIME,此时的结果为:

This is MyAnnotation. ^_^

 

描述

在JavaDoc中,RetentionPolicy是这样描述的:

RetentionPolicy 说明 举例
SOURCE 注解只保留在代码中,class文件中没有 @Override, @SupressWarnings
CLASS 注解会保留在class文件中,但运行时不能取得  
RUNTIME 注解会保留在class文件中,而且运行时可以取得 @Deprecated

可以理解的是,@Override注解只是为了编译器能检查是否当前的方法真的是在复写父类的方法,而@SuppressWarnings也只是为了抑制代码中的警告而已,在代码编译之后并没有作用,所以不需要写在CLASS文件中,于是,这类注解的RetentionPolicy自然应该为SOURCE。

 

验证

为了验证以上说明,接下来,我们使用javap工具把标注有MyAnnotation注解的类A的class文件进行反编译。

RetentionPolicy.SOURCE

RetentionPolicy.CLASS

可以看到:

  • 中间包含了RuntimeInvisibleAnnotations这一部分,表明注解确实已经写入到class文件中,而且是运行时不可见的(RuntimeInvisibleAnnotations)
  • 而在常量池中,可以清楚的看到自定义注解的权限定类名,注解的属性,和属性的值均被写入到class中,而且是常量

RetentionPolicy.RUNTIME

可以看到:

  • 和CLASS一样,中间也包含了RuntimeInvisibleAnnotations这一部分,但注解是运行时可见的(RuntimeVisibleAnnotations)
  • 和CLASS一样,注解的权限定类名,注解的属性,和属性的值同样被写入到class的常量池

到这里可以得出以下结论:

  • 一个带注解的类在编译后,如果注解的RetentionPolicy是CLASS或RUNTIME,那么此注解的信息会被记录到类的量池中
  • 如果要在代码中获取注解,需要把Retention设置为RetentionPolicy.RUNTIME

 

-------------分----------割----------线-------------

另外,通过这篇博客,也印证了前文中的观点:注解信息来自类的常量池

注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。

 

 

参考链接:

https://stackoverflow.com/questions/3933119/how-to-view-annotation-of-java-classfile-via-command-line

http://blog.csdn.net/lylwo317/article/details/52163304

 

© 著作权归作者所有

共有 人打赏支持
摆渡者
粉丝 336
博文 171
码字总数 205876
作品 0
浦东
程序员
私信 提问
Java注解(Annotation)详解

Java注解(Annotation)详解 1.Annotation的概念 An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and packages may......

幻海流心
2018/05/23
0
0
Java注解教程:自定义注解示例,利用反射进行解析

Java注解能够提供代码的相关信息,同时对于所注解的代码结构又没有直接影响。在这篇教程中,我们将学习Java注解,如何编写自定义注解,注解的使用,以及如何使用反射解析注解。 注解是Java ...

哲别0
2017/10/23
0
0
ButterKnife源码解析

ButterKnife(https://github.com/JakeWharton/butterknife)是一款android平台的依赖注入框架,通过该工具可以实现View、OnClickListener的注入,省去了findViewById、setOnClickListener的...

JasmineBen
2018/05/29
0
0
「Android」Android开发你需要知道的注解(Annotation)

本文来自尚妆Android团队路飞 发表于尚妆github博客,欢迎订阅! 一、什么是注解 1、注解的作用 2、注解都有哪些 二、自定义注解 1、RetentionPolicy.SOURCE 2、RetentionPolicy.RUNTIME 3、...

尚妆产品技术刊读
2017/06/15
0
0
深入浅出Java Annotation(元注解和自定义注解)

一、基本概述    Annontation是Java5开始引入的新特征。中文名称一般叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)...

引鸩怼孑
2015/07/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

大数据教程(11.9)hive操作基础知识

上一篇博客分享了hive的简介和初体验,本节博主将继续分享一些hive的操作的基础知识。 DDL操作 (1)创建表 #建表语法CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_name ...

em_aaron
今天
2
0
OSChina 周四乱弹 —— 我家猫真会后空翻

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @我没有抓狂 :#今天听这个# 我艇牛逼,百听不厌,太好听辣 分享 Led Zeppelin 的歌曲《Stairway To Heaven》 《Stairway To Heaven》- Led Z...

小小编辑
今天
2
0
node调用dll

先安装python2.7 安装node-gyp cnpm install node-gyp -g 新建一个Electron-vue项目(案例用Electron-vue) vue init simulatedgreg/electron-vue my-project 安装electron-rebuild cnpm ins......

Chason-洪
今天
3
0
scala学习(一)

学习Spark之前需要学习Scala。 参考学习的书籍:快学Scala

柠檬果过
今天
3
0
通俗易懂解释网络工程中的技术,如STP,HSRP等

导读 在面试时,比如被问到HSRP的主备切换时间时多久,STP几个状态的停留时间,自己知道有这些东西,但在工作中不会经常用到,就老是记不住,觉得可能还是自己基础不够牢固,知识掌握不够全面...

问题终结者
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部