文档章节

关于Java的Retention元注解

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

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

 

© 著作权归作者所有

共有 人打赏支持
摆渡者
粉丝 320
博文 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
ButterKnife源码解析

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

JasmineBen
05/29
0
0
Java SE Annotations API学习

注解,元数据的一种形式,提供关于程序不是程序本身的一部分数据。注解对代码的操作没有直接影响。 注解有多用途,如: a、用于编译信息。通过编译器检测错误or抑制警告 b、编译时和部署时的...

Rksi5
2014/04/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

c语言之内存分配笔记

先看一个数组: short array[5] = {1,2} // 这儿定义的一个int类型的数组,数组第1和第2个元素值是1和2.其余后面默认会给值为0; 或者 short array[] = {1,2};//这儿数组第1和第2个元素,数组...

DannyCoder
44分钟前
0
0
Shell | linux安装包不用选择Y/N的方法

apt-get install -y packageOR echo "y" | sudo apt-get install package

云迹
今天
1
0
Hadoop的大数据生态圈

基于Hadoop的大数据的产品圈 大数据产品的一句话概括 Apache Hadoop: 是Apache开源组织的一个分布式计算开源框架,提供了一个分布式文件系统子项目(HDFS)和支持MapReduce分布式计算的软件架...

zimingforever
今天
4
0
八大包装类型的equals方法

先看其中一个源码 结论:八大包装类型的equals方法都是先判断类型是否相同,不相同则是false,相同则判断值是否相等 注意:包装类型不能直接用==来等值比较,否则编译报错,但是数值的基本类型...

xuklc
今天
2
0
NoSQL , Memcached介绍

什么是NoSQL 非关系型数据库就是NoSQL,关系型数据库代表MySQL 对于关系型数据库来说,是需要把数据存储到库、表、行、字段里,查询的时候根据条件一行一行地去匹配,当量非常大的时候就很耗...

TaoXu
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部