Java注解浅析

何为注解

注解不同于注释,注释不会写到类文件中,注解可以写入到类文件中,是一种对代码的解析辅助机制。通过对特定的代码进行注解,就可以在运行时对这部分代码做“特殊处理”。以我们常见的Java的标准注解为例,Java的内置注解有三个,分别是:
@Override: 修饰必须覆盖父类方法的方法,修饰了该注解的方法在子类中必须覆盖父类。
@SuppressWarnnings: 通知Java编译对类、方法等成员的警告。
@Deprecate: 标记过时的方法,表示后续版本不推荐使用该方法。该方法留在类中只表示“延续性”。
使用标准注解的方式非常简单。如下:

@Override
public void info(){
 ......
}

除了标准的注解之外,用户还可以定义自己的注解,举个简单例子:

public @interface MyTag {
    String name() default "";
    int age() default -1;
}

这里我创建了一个注解,该注解的名字为MyTag,之所以有@interface,表示该注解实现了java.lang.Annotation的接口。注解本质上也是一个类,上面定义了两个成员,一个是name,一个是age。注解里面使用类似方法的形式表示成员。default表示当成员没有定义时的默认值。
Java中定义了四个标准的meta-annotation(元注解),元注解的作用是注解其他注解。
1. @Target:描述注解的使用范围,取值自java.lang.annotation.ElementType的枚举值,ElementType 的值有CONSTRUCTOR(构造器)、FIELD(域)、LOCAL_VARIABLE(局部变量)、METHOD(方法)、PACKAGE(包)、TYPE(类、接口)、ANNOTATION_TYPE(注解类型)、PARAMETER(参数)。
2. @Retention:注解该注解的保留时间,取值自java.lang.annotation.RetentionPolicy,CLASS(默认,class有效)、SOURCE(源文件有效)、RUNTIME(最常见,运行时有效)。
3. @Documented:标注该注解被javadoc记录,表示注解信息也将出现在javadoc生成的文档中。
4. @Inherited:表示注解将同类一起被继承。用于子类继承父类时,父类有该注解的注解子类也继承。
使用元注解的方式非常简单,在我们自定义的注解上面加上@就可以了。

@Retention(value=RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
@Documented
@Inherited
public @interface MyTag {
    String name() default "";
    int age() default -1;
}

注解应用及处理

注解在使用时,需要考虑注解的Target,并在Target元素上使用@标记。如:

public class MyTagTest {
    @MyTag(name="Aline" , age=25)
    public void info(String name) {
        System.out.println("info"+name);
    }
    @MyTag(name="Prin" , age=26)
    public void info2() {
        System.out.println("Info2");
    }
}

这里使用我前面自定义的注解来修饰方法,在修饰时,使用(name=value)的方式进行赋值。这里我们已经在元素上应用了注解了,现在我们需要定义注解处理器,来对注解的元素进行定位和处理。这里我通过反射来对注解方法进行调用。这里由于try…catch是使用工具自动生成的,因此看起来比较长,可以忽略try…catch这部分内容。

    public void processAnno(Object obj) {
        Class<?> cl = obj.getClass();
        for(Method m : cl.getDeclaredMethods()) {
            MyTag tag = m.getAnnotation(MyTag.class);
            if (tag!=null) {
              if(tag.name().equals("Prin")) {
                try {
                    m.invoke(obj);
                } catch (Exception ex) {
                    ex.printStackTrace();
                  } 
               }
              else if(tag.name().equals("Aline")) {
                try {
                    m.invoke(obj, tag.name());
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
          }
        }
    }

这里首先使用getDeclaredMethods()方法来获取所有class文件的方法,然后对方法数组进行一一扫描,如果有annotation,则进行判断处理。
编写测试类如下:

public static void main(String args[]){
        MyTagTest mtt = new MyTagTest();
        mtt.processAnno(mtt);
    }

输出结果为:
Info2
infoAline

本文主要参考以下网络文章:
http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值