• 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


  • 相关阅读:
    C语言指向指针的指针
    C语言注意事项
    C语言指针
    C语言字符串
    C语言数组
    C语言交换两个数的值
    C语言位运算符
    C语言各种进制输出
    C语言中各种进制的表示
    C 语言sizeof运算符
  • 原文地址:https://www.cnblogs.com/hehe520/p/6330005.html
Copyright © 2020-2023  润新知