java 注解

一.java内置的七个注解

三个标准注解

  1. @Override : 表示当前的方法定义将覆盖超类中的方法。
  2. @Deprecated : 如果程序员使用了注解为它的元素,那么编译器会发出警告信息。
  3. @SuppressWarnings : 关闭不当的编译器警告信息

四个元注解:元注解专职负责注解其他的注解
1.@Target : 表示该注解可以用于什么地方。接受参数包括:
ElementType.CONSTRUCTOR : 构造器的声明
ElementType.FIELD : 域声明(包括enum实例)
ElementType.LOCAL_VARIABLE : 局部变量声明
ElementType.METHOD : 方法声明
ElementType.PACKAGE : 包声明
ElementType.PARAMETER : 参数声明
ElementType.TYPE : 类、接口(包括注解类型) 或 enum声明

ElementType本质上就是个枚举(enum)
如果@Target要指定多个值,以“,”分隔,用法如下:

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

如果注解应用于所有类型,那么不加@Target,即可

2.@Retention : 表示需要在什么级别保存该注解信息。接受参数包括:
RetentionPolicy.SOURCE : 注解将被编译器丢弃。
RetentionPolicy.CLASS : 注解在class文件中可用,但会被VM丢弃。
RetentionPolicy.RUNTIME : VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息

3.@Documented : 将此注解包含在Javadoc中。

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

二.基本语法
1.定义注解
注解的定义看起来像接口的定义。事实上,与其他任何java接口一样,直接也将会编译成class文件

package annotations;

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 UseCase {
    public int id();
    public String description() default "no description"; 
    // default 如果在注解某个方法时没有给出description的值,则该注解的处理器就会使用此元素的默认值
}

注解元素说明:
注解@UseCase由UseCase.java定义,其中包含int元素id,以及一个String元素description。
注解元素可用的类型如下所示:
*所有基本类型:int,float,boolean等
*String
*Class
*enum
*Annotation
*以上类型的数组
如果你使用了其他类型,那么编译器就会报错。注意,也不允许使用任何包装类型,不过由于自动装箱的存在,这算不是什么限制。注解也可以作为元素的类型,也就是说注解可以嵌套。

2.注解的使用

package annotations;

import java.util.List;

public class PasswordUtils {

    @UseCase(id = 47, description = "Passwords must contain at least on numeric")
    public boolean validatePassword(String password) {
        return (password.matches("\\w*\\d\\w*"));
    }

    @UseCase(id = 48)
    public String encryptPassword(String password) {
        return new StringBuilder(password).reverse().toString();
    }
    
    @UseCase(id = 49, description = "New passwords can't equal previously used ones")
    public boolean checkForNewPassword(List<String> prevPasswords, String password) {
        return !prevPasswords.contains(password);
    }
}

3.编写注解处理器
如果没有用来读取注解的工具,那么注解也不会比注释更有用。使用注解的过程中,很重要的一部分就是创建与使用注解处理器。java SE5扩展了反射机制的API,以帮助程序员构造这类工具。
下面是一个非常简单的注解处理器,并使用反射机制查找 @UseCase标记。

package annotations;//: annotations/UseCaseTracker.java

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

public class UseCaseTracker {
    public static void
    trackUseCases(List<Integer> useCases, Class<?> cl) {
        for (Method m : cl.getDeclaredMethods()) {
            UseCase uc = m.getAnnotation(UseCase.class);
            if (uc != null) {
                System.out.println("Found Use Case:" + uc.id() + " " + uc.description());
                useCases.remove(new Integer(uc.id()));
            }
        }

        for (int i : useCases) {
            System.out.println("Warning: Missing use case-" + i);
        }
    }

    public static void main(String[] args) {
        List<Integer> useCases = new ArrayList<Integer>();
        Collections.addAll(useCases, 47, 48, 49, 50);
        trackUseCases(useCases, PasswordUtils.class);
    }
} 
/* Output:
Found Use Case:47 Passwords must contain at least one numeric
Found Use Case:48 no description
Found Use Case:49 New passwords can't equal previously used ones
Warning: Missing use case-50
*///:~

三.说明
1.编译器对元素的默认值有些过分挑剔。首先,元素不能有不确定的值。也就是说,元素必须要么有默认值,要么在使用注解时提供元素的值。
其次,对于非基本类型的元素,无论是在源代码中声明时,或是在注解接口中定义默认值时,都不能以null作为其值。这个约束使得处理器很难表现一个元素的存在或缺失的状态,因为在每个注解的声明中,所有的元素都存在,并且都具有相应的值。为了绕开这个约束,我们只能自己定义一些特殊的值,例如空字符串或负数,以此表示某个元素不存在
eg:

package annotations;

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 SimulatingNull {
    public int id() default -1;

    public String description() default "";
}

2.当注解元素为value时,使用注解可以直接传值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值