您的位置:首页 > 编程语言 > Java开发

Java反射—结合框架谈注解

2016-02-26 14:08 351 查看

1.   概念

       首先,要理解注解的作用。注解的作用很简单、明确,它就是一种标记。在程序中加入了注解,就等于为程序(例如:类、方法)打上了某种标记;没加注解,则表示没有加标记。以后,我们就可以在其它程序中通过反射来得到,加了注解的有哪些类,没加注解的有哪些类。这样就可以对这两种类进行不同的处理。

       例如,我们可以在Spring中定义一个注解@SpringClazz,如果类上面打了这个注解,就代表这个类被Spring容器管理了,于是用到这个类时,我们的工厂要返回这个目标类的【代理对象】。当然,如果没有打这个注解,就代表这个类没有被Spring容器管理,于是我们的工厂直接返回目标类的对象。(详情可以看上一篇文章http://blog.csdn.net/wang379275614/article/details/47112195

       上面只是定义了一个最简单的注解,注解还有属性等,下面我们就简单、系统的介绍一下java中的注解。

2.    系统注解

       在java.lang包下,我们可以看到jdk默认提供的三个注解:

  


3.    元注解

       即,注解的注解,就是用在我们的注解定义上的注解。类似我们数据表中经常说的元数据。概念不再多说,这里介绍两个很重要的元注解@Retention与@Target。

  Ø  @Retention(指定注解的作用时机:源代码、编译时、运行时)

  Ø  @Target(指定注解的作用范围:类【Type】、方法。。。。)

  例如@Override注解的定义如下:

  


  @Retention指定注解作用的时机,代表了我们在哪个阶段来检查相应的目标注解。例如@Override注解一定是在源代码时就开始检测,如果我们写代码时不符合@Override的规范,肯定等不到编译,就会提示我们用法错误。它的值为RetentionPolicy枚举,枚举常量有如下几种:(不需要记住,在jdk api文档中随便找一个注解都能找到它)

  


  @Target,指定注解作用的范围,如果我们指定作用范围为方法,那么我们就不能将该注解加到其它类型的元素上,例如加到类的上面就会报错。它的取值为ElementType枚举,枚举常量有如下几种:

  


4.    注解属性

       例如我们定义了一个注解@Tsinghua来标识是清华大学的学生,但程序还需要知道你是清华大学哪个系的学生,我们就可以给@Tsinghua这个注解加一个department属性。如:@Tsinghua(department=”Math”)就可以表示你是清华大学数学系的学生。

5.    自定义注解

       直接看代码:

  5.1   自定义注解@TGBAnnotation:

[java] view
plain copy

package com.tgb.TestAnnotation;  

  

import java.lang.annotation.ElementType;  

import java.lang.annotation.Retention;  

import java.lang.annotation.RetentionPolicy;  

import java.lang.annotation.Target;  

  

@Target( { ElementType.METHOD, ElementType.TYPE })  

@Retention(RetentionPolicy.RUNTIME)  

public @interface TGBAnnotation {  

    // 注解属性1  

    String color() default "blue";  

  

    // 注解属性2  

    int[] score() default { 1, 2, 3 };  

  

}  

  上面这个注解有两个注解属性;在运行时起作用;可以加在类、方法两种元素上。

  5.2   测试类AnnotationTest:

[java] view
plain copy

package com.tgb.TestAnnotation;  

  

@TGBAnnotation(color = "class--->yellow", score = { 10, 20 })  

public class AnnotationTest {  

  

    public static void main(String[] args) throws Exception {  

        // 已废弃的方法,比较危险,但也能用  

        System.runFinalizersOnExit(true);  

        sayHi();  

    }  

  

    /* 

     * 当我们版本升级时,不想删掉以前的代码,也不想注释大量的代码,就可以加上@Deprecated注解 

     */  

    @Deprecated  

    public static void sayHello() {  

        System.out.println("Hello world!");  

    }  

  

    /** 

     * 测试注解 

     */  

    @TGBAnnotation(color = "method--->red")  

    public static void sayHi() throws Exception {  

        // 如果AnnotationTest这个类上存在注解ItCastAnnotation  

        if (AnnotationTest.class.isAnnotationPresent(TGBAnnotation.class)) {  

            // 得到AnnotationTest类上的ItCastAnnotation注解实例,进而可以获得注解上的属性  

            TGBAnnotation annotation = AnnotationTest.class.getAnnotation(TGBAnnotation.class);  

            TGBAnnotation annotation2 = AnnotationTest.class.getMethod("sayHi", null).getAnnotation(TGBAnnotation.class);  

            System.err.println("annotation---->" + annotation.color());// 输出:class--->yellow  

            System.err.println("annotation2--->" + annotation2.color());// 输出:method--->red  

  

            int[] score = annotation.score();  

            for (int i : score) {  

                System.out.println(i);// 依次输出:10、20  

            }  

        }  

    }  

}  

6.    总结

  注解的作用很简单、明确,它就是一种标记。例如加上Spring的某个注解来标识这个类由Spring容器管理,getBean时返回【代理对象】;没有加这个注解的表示没有加到Spring容器中,getBean时直接返回【目标对象】。此外,结合jdk默认自带注解与张孝祥老师的所言,.class文件中的东西不是“字节码”,当类加载器把.class文件加载到内存的过程中也会处理一些事(例如安全检查),处理完以后的加载到内存中的二进制东西才是字节码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: