thinking-in-java(20)注解入门荔枝
2017-12-27 23:39
344 查看
【1】定义注解
有了注解的绑定,原有的代码节点可以有许多附加的信息;而且注解使得代码的复用性强和复用更加便利!!
// 荔枝-使用注解来跟踪一个项目中的用例 // 下面定义了一个注解UseCase:该注解作用于方法,该注解在运行时发挥作用 @Target(ElementType.METHOD) // 该注解应用于什么地方 @Retention(RetentionPolicy.RUNTIME) // 该注解的应用级别,源代码-SOURCE, 类文件中-CLASS, 运行时-RUNTIME public @interface UseCase { public int id(); public String description() default "no description"; // no description 是默认值 } // /:~ /* 反编译后的源码:可以看到,注解就是一个接口类型,该接口的父类是 Annotation 注解接口类型,当然了,接口中的方法都是抽象方法 E:\bench-cluster\spring_in_action_eclipse\AThinkingInJava\src>javap -c chapter20.UseCase Compiled from "UseCase.java" public interface chapter20.UseCase extends java.lang.annotation.Annotation { public abstract int id(); public abstract java.lang.String description(); } */【2】将注解作用于方法(也可以作用于其他地方:如CONSTRUCTOR, FIELD, METHOD, LOCAL_VARIABLE, PACKAGE, PARAMETER, TYPE等)
// 荔枝-有3个方法被注解为用例 public class PasswordUtils { // 将 UseCase 注解作用于方法 @UseCase(id = 47, description = "Passwords must contain at least one numeric") public boolean validatePassword(String password) { return (password.matches("\\w*\\d\\w*")); } @UseCase(id = 48) // description 默认为 no description 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); } } // /:~
/* 反编译简要结果如下: E:\bench-cluster\spring_in_action_eclipse\AThinkingInJava\src>javap chapter20.PasswordUtils Compiled from "PasswordUtils.java" public class chapter20.PasswordUtils { public chapter20.PasswordUtils(); public boolean validatePassword(java.lang.String); public java.lang.String encryptPassword(java.lang.String); public boolean checkForNewPassword(java.util.List<java.lang.String>, java.lang.String); } */
/* 反编译详细结果如下: E:\bench-cluster\spring_in_action_eclipse\AThinkingInJava\src>javap -c chapter20.PasswordUtils Compiled from "PasswordUtils.java" public class chapter20.PasswordUtils { public chapter20.PasswordUtils(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public boolean validatePassword(java.lang.String); Code: 0: aload_1 1: ldc #2 // String \w*\d\w* 3: invokevirtual #3 // Method java/lang/String.matches:(Ljava/lang/String;)Z 6: ireturn public java.lang.String encryptPassword(java.lang.String); Code: 0: new #4 // class java/lang/StringBuilder 3: dup 4: aload_1 5: invokespecial #5 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 8: invokevirtual #6 // Method java/lang/StringBuilder.reverse:()Ljava/lang/StringBuilder; 11: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 14: areturn public boolean checkForNewPassword(java.util.List<java.lang.String>, java.lang.String); Code: 0: aload_1 1: aload_2 2: invokeinterface #8, 2 // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z 7: ifne 14 10: iconst_1 11: goto 15 14: iconst_0 15: ireturn } */【3】编写注解处理器
// 通过反射机制来编写注解处理器 public class UseCaseTracker { // cl 是使用 UseCase注解的 Class类信息对象 public static void trackUseCases(List<Integer> useCases, Class<?> cl) { for (Method m : cl.getDeclaredMethods()) { // // 通过反射获取使用UseCase注解实例的对象所声明的方法列表 UseCase uc = m.getAnnotation(UseCase.class); // 方法通过反射机制(UseCase.class)获取UseCase注解实例 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); } } /* Found Use Case:49 New passwords can't equal previously used ones Found Use Case:47 Passwords must contain at least one numeric Found Use Case:48 no description Warning: Missing use case-50 */【小结】 注解就是绑定在或作用于 代码节点(如CONSTRUCTOR, FIELD, METHOD, LOCAL_VARIABLE, PACKAGE, PARAMETER, TYPE等 )的数据的类型;
有了注解的绑定,原有的代码节点可以有许多附加的信息;而且注解使得代码的复用性强和复用更加便利!!
相关文章推荐
- thinking-in-java(20)利用注解生成创建数据库表的SQL
- thinking-in-java(20)注解基础
- Thinking in Java Ch20 注释
- 《Thinking in Java》学习笔记——第一章:对象入门
- 第1章 对象入门——Thinking-in-Java
- Thinking in Java 第20章 注解(元数据)
- 深入理解Java:注解(Annotation)自定义注解入门
- Thinking in JAVA websites
- 《thinking&nbsp;in&nbsp;java》学习笔记19
- Thinking in Java 第13章:并发
- java 注解:注解(Annotation)自定义注解入门
- Note of 《thinking in java》4
- 《Thinkinginjava》第15章-泛型
- Thinking in java(一)
- 《Thinking in Java》——final关键字
- Notes Of Thinking In Java (1)
- 深入理解Java:注解(Annotation)自定义注解入门
- 测试对象的等价性(Thinking in Java 4th Edition)
- Thinking in Java中文版 1
- 《Thinking in java》读书笔记