注解(java编程思想)
参考:java编程思想
什么是注解
又叫元数据,JDK5引入的一种以通用格式为程序提供配置信息的方式。使用注解Annotation可以使元数据写在程序源码中,使得代码看起来简洁,同时编译器也提供了对注解Annotation的类型检查,使得在编译期间就可以排除语法错误。注解使得我们能够以将由编译器来测试和验证的格式,存储有关程序的额外信息。注解可以用来生成描述符文件,甚至是新的类定义,并且有助于减轻编写"样板"代码的负担。
jdk5中内置了3个通用的注解
@Override:这个注解常用在继承类或实现接口的子类方法上,表面该方法是子类覆盖父类的方法,该方法的方法签名要遵循覆盖方法的原则:即访问控制权限必能比父类更严格,不能比父类抛出更多的异常。
@Deprecated:这个注解告诉编译器该元素是过时的,即在目前的JDK版本中已经有新的元素代替该元素。
@SuppressWarnings:该注解关闭编译器中不合适的警告,即强行压制编译器的警告提示。
定义注解
元注解(meta-annotation):在声明注解的时候往往需要使用@Target,@Retention等注解,这种注解被称为注解的注解(元数据注解),即是专门用于处理注解Annotation本身的。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test{}
元注解
@Target @Retention @Documented @Inherited
编写注解处理器
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface UseCase{ public int id(); public String description() default “no description”; //可以定义属性默认值 }
public class PasswordUtils{ @UseCase(id = 47, description = “Passwords must contain at least one numeric”) public Boolean validatePassword(String password){ return (password.mathes(“\\w*\\d\\w*”)); } @UseCase(id = 48) public String encryptPassword(Srring 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); }
使用,获取注解方法
public class UseCaseTracker{ public static void traceUseCases(List<Integer> useCases, Class<?> clazz){ //获取指定类中所有声明的方法 for(Method m : clazz.getDeclaredMethods()){ //获取方法上指定类型的注解 public class UseCaseTracker{ public static void traceUseCases(List<Integer> useCases, Class<?> clazz){ //获取指定类中所有声明的方法 for(Method m : clazz.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 ArrayLis<Integer>(); Collections.addAll(useCases, 47, 48, 49, 50); trackUseCases(useCases, PasswordUtils.class); } }
这个程序用到了两个反射的方法:getDeclaredMethods()和m.getAnnotation(UseCase.class):getDeclaredMethods() 返回类声明的方法 m.getAnnotation(UseCase.class) 返回指定类型的注解对象。如果被注解的方法上没有该类型的注解,则返回null值。
Annotation注解元素
Annotation注解中的元素只能是下面的数据类型:
所有的基本类型(int,float,boolean等): java的8种基本类型,如int, boolean等等,如果可以自动装箱和拆箱,则可以使用对应的对象包装类型。String、Class、enum、Annotation上面类型的数组
除了上面这些类型以外,如果在注解中定义其他类型的数据,编译器将会报错。
默认值限制
注意:注解中的元素要么指定默认值,要么由使用的类赋值,如果即没有默认值,使用类也没有赋值的话,注解元素是不会像普通类成员变量一样给定默认值,即必须赋值或者显示指定默认值。默认值例子如下:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DefaultValue{
public int id() default -1;
public String description() default “”;
}