文档章节

关于Java的Retention元注解

摆渡者
 摆渡者
发布于 2017/08/29 16:55
字数 736
阅读 360
收藏 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

 

© 著作权归作者所有

共有 人打赏支持
摆渡者
粉丝 330
博文 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......

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

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

哲别0
2017/10/23
0
0
「Android」Android开发你需要知道的注解(Annotation)

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

尚妆产品技术刊读
2017/06/15
0
0
解惑Java注解类型(待更新)

java注解是在JDK5时引入的新特性,鉴于目前大部分框架(如Spring)都使用了注解简化代码并提高编码的效率,因此掌握并深入理解注解对于一个Java工程师是来说是很有必要的事。本篇我们将通过以下...

芥末无疆sss
10/09
0
0
ButterKnife源码解析

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

JasmineBen
05/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

WinDbg

参考来自:http://www.cnit.net.cn/?id=225 SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols ctrl + d to open dump_file Microsoft (R) Windows Debugger Version 6.12.0002.633......

xueyuse0012
31分钟前
2
0
OSChina 周五乱弹 —— 想不想把92年的萝莉退货

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @罗马的王:分享松澤由美的单曲《地球ぎ》 很久没看圣斗士星矢了 《地球ぎ》- 松澤由美 手机党少年们想听歌,请使劲儿戳(这里) @开源中国首...

小小编辑
58分钟前
10
1
springBoot条件配置

本篇介绍下,如何通过springboot的条件配置,控制Bean的创建 介绍下开发环境 JDK版本1.8 springboot版本是1.5.2 开发工具为 intellij idea(2018.2) 开发环境为 15款MacBook Pro 前言 很多时候,...

贺小五
今天
1
0
javascript source map 的使用

之前发现VS.NET会为压缩的js文添加一个与文件名同名的.map文件,一直没有搞懂他是用来做什么的,直接删除掉运行时浏览器又会报错,后来google了一直才真正搞懂了这个小小的map文件背后的巨大...

粒子数反转
昨天
1
0
谈谈如何学Linux和它在如今社会的影响

昨天,还在农耕脑力社会,今天已经人工智能技术、大数据、信息技术的科技社会了,高速开展并迅速浸透到当今科技社会的各个方面,Linux日益成为人们信息时代的到来,更加考验我们对信息的处理程...

linux-tao
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部