开发者学堂课程【Java 高级编程:反射取得 Annotation 信息】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/20/detail/396
反射取得 Annotation 信息
内容简介:
1.具体内容
2.获取 Annotation 信息
3.范例
4.Annotation 的读取操作
1.具体内容
从 JDK1.5 之后 Java 开发提供了 Annotation 技术支持,这种技术为项目的编写带来新的模型,而后经过了十多年的发展,Annotation 技术得到了非常广泛的应用,并且已经在所有项目开发之中都会存在。
2.获取 Annotation 信息
在进行类或方法定义的时候都可以使用一系列的 Annotation 进行声明,于是如果要想获取这些 Annotation 的信息,那么就可以直接通过反射来完成。在java.lang.reflect 里面有一个 AccessibleObject 类,在本类中提供有获取Annotation 类的方法。
如果 AccessibleObject 类中有这些方法的话,那么构造方法、普通方法里面,包括成员里面都会具有这些操作。在代码中找到程序包,Java.lang.reflect 打开之后,找到 AccessibleObject,ExecutableField,这是 Class 类中的几个核心组成。之前所学习的所有反射的结构操作实际上都是 Accessible 子类展开的,操作方法有以下几种:
1)获取全部Annotation:public Annotation[] getAnnotations();
2)获取指定Annotation:public<T extends Annotation> T getAnnotation(Class<T> annotationClass)
获取完成之后,返回的都是 Annotation 的对象,打开 annotation,点击打开发现Annotation 是接口,这个接口是在 1.5 之后有的,如下图:
对于构造方法等信息的获得是通过 Class 类完成的,既然要想完成 Annotation,至少应该得有一些结构上具备有 Annotation 的相关信息:
3.范例
范例:定义一个接口,并且在接口上使用 Annotation。
现在有两个 Annotation,要想获取 Annotation 有两种处理方式:
1)第一种处理方式的代码如下:
public class JavaAPIDemo {
public static void main(String[] args) throws Exception{
{ // 获取接口上的Annotation信息
Annotation annotations [] = IMessage.class. getAnnotations() ; // 获取接口上的全部Annotation
for (Annotation temp : annotations) {
System.out .printIn(temp);
}
}
程序执行的结果如下:
@java . lang. FunctionalInterface( )
@java . lang. Deprecated ( forRemoval=false, since="" )
其中,since 指的是版本,可以增加 since=“1.0“ 的时候废除:
@FunctionalInterface
@Deprecated(since="1.0")
interface IMessage { // 有两个Annotation
public void send(String msg) ;
}
执行结果如下:
@java. lang. FunctionalInterface( )
@java. lang. Deprecated(forRemoval=false, since="1.0")
2)第二种处理方式的代码如下:
System. out . printIn(---------------------------");
{ // 获取MessageImpl子类上的Annotation
Annotation annotations [] = MessageImpl. class. getAnnotations() ; // 获取接口上的全部Annotation
for (Annotation temp : annotations) {
System. out . println(temp);
}
执行结果如下:
@java. lang. FunctionalInterface()
@java. lang . Deprecated ( forRemoval=false, since="1.0")
这个 Annotation 无法在程序执行的时候获取。
再增加一个操作,获取 toString()方法,代码如下:
System. out. printIn(“ -----------------------------”);
{ // 获取MessageImpl . toString( )方法上的Annotation
Method method = MessageImpl . class . getDeclaredMethod("send", String.class) ;
Annotation annotations [] = method . getAnnotations() ; // 获取接口上的全部Annotation
for (Annotation temp : annotations) {
System. out printIn(temp);
}
}
执行结果如下:
@java .1ang. FunctionalInterface( )
@java. lang . Deprecated ( forRemoval=false, since="1.0")
还是无法在程序执行的时候获取。
4.Annotation 的读取操作
发现有些 Annotation 是可以获取的,而有些 Annotation 无法进行获取。不同的Annotation 有它的存在范围,下面对比两个 Annotation:
@FunctionalInterface (运行时)
@Documented
@Retention( RetentionPolicy . RUNTIME)
@Target( ElementType. TYPE)
public @interface FunctionalInterface { }
@Suppresswarnings ( 源代码)
@Target({ TYPE,FIELD, METHOD,PARAMETER,
CONS TRUCTOR,LOCAL_ VARIABLE, MODULE})
@Retention ( RetentionPolicy . SOURCE)
public @interface SuppressWarnings { }
现在发现“@FunctionalInterface“是在运行时生效的 Annotation,所以当程序执行的时候可以获取此 Annotation,而“@SuppressWarnings”是在源代码编写的时候有效。而在 RetentionPolicy 枚举类中还有一个 class 的定义,指的是在类定义的时候生效。
不同的 Annotation 的策略是它能否被程序读取的关键性因素,以上就是annotation 的读取操作。