JAVA自定义注解与通过反射去解析注解参数

 

一,概念:

 

注解是 JDK5 引入的新特性,最初衍生自代码注释,但现在早已经超出了注释的范畴,以至于我很惶恐,不敢使用注释这个词汇来描述他,尽管现有的很多资料里仍然称其为注释。如果说反射使得很多技术实现(动态代理、依赖注入等)有了基础,那么注解就是使这些技术实现变得平民化的基础。

 

从 class 文件规范中可以看出, JDK5 开始, class 文件已经引入了注解描述片段。站在 java 虚拟机的角度来看, class 保留和运行时保留的注解已经和 java 二进制码放在了同等的地位。虚拟机在加载 class 文件时,会为注解内容分配空间并进行解析,最终还会为注解和对应的二进制码建立关联。尽管这些注解不会被运行,但其对代码的说明能力,结合反射技术已经足够我们做太多的事情。

 

我们知道, java 除了内置的注解( @Override 、 @Deprecated 等)以外,还支持自定义注解( Struts 、 Hibernate 等很多框架甚至 java 自身都实现了很多自定义注解)。当然,更为厉害的是元注解,元注解是用来描述注解的注解。

 

要实现一个自定义注解,必须通过 @interface 关键字来定义。且在 @interface 之前,需要通过元注解来描述该注解的使用范围( @Target )、生命周期( @Retention )及其他(其他的不重要)

 

@Target 用于描述注解的使用范围(即:被描述的注解可以用在什么地方),其取值有:

取值描述
CONSTRUCTOR用于描述构造器
FIELD用于描述域
LOCAL_VARIABLE用于描述局部变量
METHOD用于描述方法
PACKAGE用于描述包
PARAMETER用于描述参数
TYPE 用于描述类或接口(甚至 enum 

 

@Retention 用于描述注解的生命周期(即:被描述的注解在什么范围内有效),其取值有:

取值描述
SOURCE在源文件中有效
CLASS class 文件中有效
RUNTIME在运行时有效(即运行时保留   常用)

 

下面直接看例子:

首先定义几种不同类型的注解方式

1,作用于类上面的

 

@Target(ElementType.TYPE)//用于描述类或接口
@Retention(RetentionPolicy.RUNTIME)
public @interface MyClassAnnotation {
	 String uri();  
	 String desc(); 
}

 2,作用于字段上面的

 

 

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyFieldAnnotation {
	 String uri();  
	 String desc(); 
}

 3,作用于构造上面的

 

 

@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyConstructorAnnotation {
	 String uri();  
	 String desc(); 
}

 4,作用于方法上面

 

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyMethodAnnotation {
	 String uri();  
	 String desc(); 
}

 

 

通过实例看看怎么使用吧....

public class MyAllAnnotationTest {
	
	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		
		MySample sample = new MySample();
		Class clazz = sample.getClass();
		//类
		boolean c = clazz.isAnnotationPresent(MyClassAnnotation.class);
		if (c) {
			MyClassAnnotation myClassAnnotation = (MyClassAnnotation) clazz.getAnnotation(MyClassAnnotation.class);
			printMyClassAnnotation(myClassAnnotation);
		}
		
		//构造
		Constructor[] constructors = clazz.getConstructors();
		for (Constructor constructor : constructors) {
			boolean cc = constructor.isAnnotationPresent(MyConstructorAnnotation.class);
			if (cc) {
				MyConstructorAnnotation myConstructorAnnotation = (MyConstructorAnnotation) constructor.getAnnotation(MyConstructorAnnotation.class);
				printMyConstructorAnnotation(myConstructorAnnotation);
			}
		}
		
		//字段
		Field[]  fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			boolean f = field.isAnnotationPresent(MyFieldAnnotation.class);
			if (f) {
				MyFieldAnnotation myFieldAnnotation = (MyFieldAnnotation)field.getAnnotation(MyFieldAnnotation.class);
				printMyFieldAnnotation(myFieldAnnotation);
			}
		}
		
		//方法
		Method[] methods = clazz.getDeclaredMethods();
		for (Method method : methods) {
			boolean m = method.isAnnotationPresent(MyMethodAnnotation.class);
			if (m) {
				MyMethodAnnotation methodAnnotation = (MyMethodAnnotation)method.getAnnotation(MyMethodAnnotation.class);
				printMyMethodAnnotation(methodAnnotation);
			}
		}
	}
	
	
	public static void printMyClassAnnotation(MyClassAnnotation myClassAnnotation){
		if (null == myClassAnnotation) {
			return;
		}
		System.out.println("url = " + myClassAnnotation.url());
		System.out.println("desc = " + myClassAnnotation.desc());
		
	}
	public static void printMyConstructorAnnotation(MyConstructorAnnotation myConstructorAnnotation){
		if (null == myConstructorAnnotation) {
			return;
		}
		System.out.println("url = " + myConstructorAnnotation.url());
		System.out.println("desc = " + myConstructorAnnotation.desc());
	}
	public static void printMyFieldAnnotation(MyFieldAnnotation myFieldAnnotation){
		if (null == myFieldAnnotation) {
			return;
		}
		System.out.println("url = " + myFieldAnnotation.url());
		System.out.println("desc = " + myFieldAnnotation.desc());
	}
	
	
	public static void printMyMethodAnnotation(MyMethodAnnotation methodAnnotation){
		if (null == methodAnnotation) {
			return;
		}
		System.out.println("url = " + methodAnnotation.url());
}
 

 

打印结果如下所示:

 

url = cn.cd.sg.test.reflect.MySample
desc = The Class Name For MySample
url = cn.cd.sg.test.reflect.MySample#MySample For Constructor
desc = The default constuctor Name For MySample()
url = cn.cd.sg.test.reflect.MySample#id
desc = The Field Name For Id
url = cn.cd.sg.test.reflect.MySample#name
desc = The Field Name For Name
url = cn.cd.sg.test.reflect.MySample#setId
desc = The Mrthod Name For setId()
url = cn.cd.sg.test.reflect.MySample#getName
desc = The Mrthod Name For getName()
url = cn.cd.sg.test.reflect.MySample#getId
desc = The Mrthod Name For getId()
url = com.sg.annotation.MySample#setName
desc = The Mrthod Name For setName()
 

 

 

以上就是JAVA自定义注解的一个小例子,深入的在去研究,先入个门再说,呵呵........

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值