JAVA中的注解技术(一)

注解技术是JAVA5中的新特性,它为我们在代码中添加信息提供了一种形式化的方法。我们在代码中通过注解的形式添加一些元数据,在将来的某个时刻就可以使用这些元数据。注解在一定程度上把元数据和源代码文件结合在一起,而不是保存在外部文件中。下面我们通过代码来领会注解技术的实现和使用。

一、定义注解

package com.annotation.demo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD) //这里不能加分号
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    public int id();
    public String description() default "no description";
}

首先我们必须导入一些必要的包为我们定义注解提供支撑。我们在定义自己注解时要先使用元注解(@Target和@Retention)对我们自己的注解进行说明。 @Target(ElementType.METHOD)  表示我们定义的注解将用于方法当中
@Retention(RetentionPolicy.RUNTIME) 表示我们的注解在运行时会被使用

二、注解的使用

上面我们定义的注解看起来和定义一个接口很类似。内部定义了两个成员,int和string类型。下面我们先来看看我们如何使用写好的这个注解。

package com.annotation.demo;
import java.util.List;

public class PasswordUtils {
    @MyAnnotation(id = 1, description = "abcdefg")
    public boolean validatePassword(String password) {
        return (password.matches("\\w*\\d\\w*"));
    }

    @MyAnnotation(id = 2)
    public String encryptPassword(String password) {
        return new StringBuilder(password).reverse().toString();
    }
   
  public void test(){
    //TODO
  }
@MyAnnotation(id
= 4, description = "fefggeff") public boolean checkForNewPassword(List<String> prevPassword, String password) { return !prevPassword.contains(password); } }

因为前面表明我们的注解是用于方法中的,所以我们需将注解写到每个方法的前面。如果写在类的前面,编译器会直接报错。注解中有两个成员,我们可以像代码中所示的那样对其赋值。description是有默认值的,不赋值的话会采用默认值,但id必须赋值。

附:JAVA中注解的元注解

元注解对我们定义的注解进行描述

 @Target  表明该注解使用的位置,如ElementType.METHOD
      ElementType的参数如下:

    CONSTRUCTOR:用于描述构造器
    FIELD:用于描述域
    LOCAL_VARIABLE:用于描述局部变量
    METHOD:用于描述方法
    PACKAGE:用于描述包
    PARAMETER:用于描述参数
    TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention 表示需要在什么级别保存该注解,即注解的生命周期,如RetentionPolicy.RUNTIME
      RetentionPolicy的参数如下:

    SOURCE:注解在源文件可用,但将来会被编译器丢弃
    Class:注解在class文件中可用,但将来会被JVM丢弃
    RUNTIME:JVM将在运行期间也保留注解,因此可以通过发射机制来读取注解的信息

@Document 将此注解包含在javadoc中

@Inherited 允许子类继承父类中的注解

三、注解的处理

前面我们已经了解到如何定义一个注解以及对其进行使用,但是我们曾提到注解的意义在于将一些原始数据保存到context中。如果我们对其不进行处理,那么注解将毫无意义。下面我们来实现如何从注解中获取原始数据。

package com.annotation.demo;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class UseAnntation {
    public static void main(String[] args) {
        List<Integer> myAnnotation = new ArrayList<Integer>();
        Collections.addAll(myAnnotation, 1, 2, 3, 4);
        MyAnnnotationTracker.trackMyAnnotation(myAnnotation,
                PasswordUtils.class);
    }
}

class MyAnnnotationTracker {
    public static void trackMyAnnotation(List<Integer> myAnnotation, Class<?> c1) {
        for (Method m : c1.getDeclaredMethods()) {
            MyAnnotation ma = m.getAnnotation(MyAnnotation.class);
            if (ma != null) {
                System.out.println("Found Use Case:" + ma.id() + " "
                        + ma.description());
                myAnnotation.remove(new Integer(ma.id()));
            }
        }
        for (int i : myAnnotation) {
            System.out.println("Warning: Missing usre case-" + i);
        }
    }
}

我们利用反射的方式获取PasswordUtils类的所有成员方法,通过getAnnotation()来查看该方法是否被添加注解。若添加了注解则输出注解的信息。将上面三部分的功能整合起来,我们可以实现下面的功能。

查找一个类中空方法与非空方法,如果有空方法则给出警告(未使用的注解的方法都被认为空方法)

posted @ 2016-01-22 13:54  被罚站的树  阅读(435)  评论(0)    收藏  举报