博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JAVA自定义注解与通过反射去解析注解参数
阅读量:4151 次
发布时间:2019-05-25

本文共 4630 字,大约阅读时间需要 15 分钟。

 

一,概念:

 

注解是 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.MySampledesc = The Class Name For MySampleurl = cn.cd.sg.test.reflect.MySample#MySample For Constructordesc = The default constuctor Name For MySample()url = cn.cd.sg.test.reflect.MySample#iddesc = The Field Name For Idurl = cn.cd.sg.test.reflect.MySample#namedesc = The Field Name For Nameurl = cn.cd.sg.test.reflect.MySample#setIddesc = The Mrthod Name For setId()url = cn.cd.sg.test.reflect.MySample#getNamedesc = The Mrthod Name For getName()url = cn.cd.sg.test.reflect.MySample#getIddesc = The Mrthod Name For getId()url = com.sg.annotation.MySample#setNamedesc = The Mrthod Name For setName()
 
 

 

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

 

 

转载地址:http://enlti.baihongyu.com/

你可能感兴趣的文章
DeepLearning tutorial(7)深度学习框架Keras的使用-进阶
查看>>
人脸识别(OpenCV+Python)
查看>>
6个强大的AngularJS扩展应用
查看>>
第三方SDK:讯飞语音听写
查看>>
第三方SDK:JPush SDK Eclipse
查看>>
第三方开源库:imageLoader的使用
查看>>
自定义控件:飞入飞出的效果
查看>>
自定义控件:动态获取控件的高
查看>>
第三方开源库:nineoldandroid:ValueAnimator 动态设置textview的高
查看>>
第三方SDK:百度地图SDK的使用
查看>>
Android studio_迁移Eclipse项目到Android studio
查看>>
JavaScript setTimeout() clearTimeout() 方法
查看>>
CSS border 属性及用border画各种图形
查看>>
转载知乎-前端汇总资源
查看>>
JavaScript substr() 方法
查看>>
JavaScript slice() 方法
查看>>
JavaScript substring() 方法
查看>>
HTML 5 新的表单元素 datalist keygen output
查看>>
(转载)正确理解cookie和session机制原理
查看>>
jQuery ajax - ajax() 方法
查看>>