Java Annotation详解(二): 反射和Annotation

简介:

前面一篇文《Java Annotation详解(一): 理解和使用Annotation》中,我们或许会觉得,Annotation注释其实并没有多大的作用,除了几个内建的Annotation偶尔为了消除警告会使用下,自定义Annotation大家在实际的开发中应该都没有用过。其实呢,我在毕业后一年的工作里,也从未自定义使用过Annotation,只是在多处开发中使用过注释方便的内容,比如Servlet,Spring以及一些优秀的Android开源类库。 如果从简单的开发来讲,大家基本会使用一些开源的工具(只使用Annotation编写的)就好了,但是,如果大家能深入的了解Annotation,对大家学习这些开源框架将更有帮助。

Annotation何时才变得有意义呢? 如果结合反射,取得Annotation中设置的全部内容,Annotation的意义才会被最大化。


在以下的类中Class Constructor Field Method Package等类都实现了AnnotatedElement接口
在接口中有以下重要的方法:
· getAnnotations(Class annotationType)获取一个指定的annotation类型
· getAnnotations() 获取所有的Annotation
· getDeclaredAnnotations() 获取声明过的所有Annotation
· isAnnotationPresent(Class<? extends Annotation> annotationClass)这个annotation是否出现

通过这些方法,配合反射我们就可以在程序运行时拿到注解的内容了,例子如下:

首先定义一个普通的含有内建注释的类:

package com.test.reflectannotation ;
public class SimpleBeanOne{
	@SuppressWarnings("unchecked") 
	@Deprecated
	@Override
	public String toString(){
		return "Hello World!!!" ;
	}
};
接下来,我们通过反射取出Annotation内容要注意,只有Deprecated的Annotation的定义范围是RUNTIME范围,所以此时通过反射的话,只能取得一个。

import java.lang.annotation.Annotation ;
import java.lang.reflect.Method ;
public class ReflectDemo01{
	public static void main(String args[]) throws Exception{	// 所有异常抛出
		Class <?> c = null ;
		c = Class.forName("com.test.SimpleBeanOne") ;
		Method toM = c.getMethod("toString") ;	// 找到toString()方法
		Annotation an[] = toM.getAnnotations() ;	// 取得全部的Annotation
		for(Annotation a:an){	// 使用 foreach输出
			System.out.println(a) ;
		}
	}
};
输出:

@java.lang.Deprecated()

以上,我们取得的是内建的Annotation,接下来,我们自己定义一个Annotation:

package com.test.reflectannotation ;
import java.lang.annotation.Retention ;
import java.lang.annotation.RetentionPolicy ;
@Retention(value=RetentionPolicy.RUNTIME)	// 此Annotation在类执行时依然有效
public @interface MyDefaultAnnotationReflect{
	public String key() default "Linkage" ;
	public String value() default "沉缘" ;

}
我们通过RetentionPolicy指定了其值为RUNTIME,在运行时有效。

package com.test.reflectannotation ;
public class SimpleBeanTwo{
	@SuppressWarnings("unchecked") 
	@Deprecated
	@Override
	@MyDefaultAnnotationReflect(key="Baidu",value="www.baidu.com")
	public String toString(){
		return "Hello World!!!" ;
	}
};

通过反射取得指定的Annotation,因为现在唯一设置的内容就是MyDefaultAnnotationReflect。

import org.lxh.demo16.reflectannotation.MyDefaultAnnotationReflect ;
import java.lang.annotation.Annotation ;
import java.lang.reflect.Method ;
public class ReflectDemo{
	public static void main(String args[]) throws Exception{	// 所有异常抛出
		Class <?> c = null ;
		c = Class.forName("com.test.reflectannotation.SimpleBeanTwo") ;
		Method toM = c.getMethod("toString") ;	// 找到toString()方法
		if(toM.isAnnotationPresent(MyDefaultAnnotationReflect.class)){
			// 判断是否是指定的Annotation
			MyDefaultAnnotationReflect mda = null ;
			mda = toM.getAnnotation(MyDefaultAnnotationReflect.class) ;	// 得到指定的Annotation
			String key = mda.key() ;	// 取出设置的key
			String value = mda.value() ;	// 取出设置的value
			System.out.println("key = " + key) ;
			System.out.println("value = " + value) ;
		}
	}
};

输出: 

key = Baidu
value = www.baidu.com

总结:

Annotation在实际的开发中,不管如何使用,其最终肯定结合反射机制,也就是说可以通过Annotation设置一些内容到方法上去,已完成特定的功能。


此外,发现有篇博客写的不错,是关于注解和反射的,可以参考:http://blog.csdn.net/a396901990/article/details/27961663


相关文章
|
1月前
|
网络协议 算法 Java
|
1月前
|
XML Java 数据库连接
谈谈Java反射:从入门到实践,再到原理
谈谈Java反射:从入门到实践,再到原理
60 0
|
1月前
|
Java 关系型数据库 MySQL
在Java的反射中,Class.forName和ClassLoader的区别
在Java的反射中,Class.forName和ClassLoader的区别
35 3
|
4天前
|
监控 Java 开发者
掌握 Java 反射和动态代理
【4月更文挑战第19天】Java反射和动态代理提供强大功能和灵活性。反射允许运行时检查和操作类,获取类信息、动态调用方法,但可能带来性能损失和降低代码可读性。动态代理则用于创建代理对象,实现透明性和横切关注点分离,常用于日志、权限检查等。两者结合能实现更复杂功能。掌握这些技术能提升代码的灵活性和可扩展性,但也需注意性能和可读性。通过学习和实践,能更好地构建高效软件系统。
|
10天前
|
Java
代码的魔法师:Java反射工厂模式详解
代码的魔法师:Java反射工厂模式详解
23 0
|
14天前
|
安全 Java
java反射篇
java反射篇
|
15天前
|
存储 Java
java反射——设计框架的灵魂
java反射——设计框架的灵魂
|
20天前
|
Java
Java通过反射获取类调用方法
Java通过反射获取类调用方法
18 0
|
29天前
|
设计模式 XML 存储
java中的反射机制
java中的反射机制
12 1
|
1月前
|
Java 数据库连接 数据库
什么是 Java 的反射
什么是 Java 的反射
9 1

热门文章

最新文章