注解(也称元数据)
三种标准注解
@Override | 表示当前方法覆盖超类中的方法 |
---|---|
@Deprecated | 使用注解为这个的元素,编译器会发出警告 |
@SuppressWarnings | 关闭不当编译器警告信息 |
20.1 基本语法
20.1.1 定义注解
package Ch20;
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 Test {}
20.1.2 元注解
@Target | 表示注解可以的地方 |
---|---|
@Retentioin | 表示需要神秘级别保存该注解信息 |
@Documented | 将注解包含在Javadoc中 |
@Inherited | 允许子类继承父类中的注解 |
20.2 编写注解处理器
没有注解处理器,注解和注释一样。
/*定义注解********************************************************/
package Ch20;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
//注解的元素看起来像接口方法。区别在于可以添加默认值
public int id();
public String description() default "no description";
}
/*使用注解*********************************************************/
package Ch20;
import java.util.*;
public class PasswordUtils {
//可以看到元素并不是方法那样定义,而是直接当变量使用。
@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)
public boolean encryptPassword(String password) {
return (password.matches("\\w*\\d\\w*"));
}
@UseCase(id =49, description = "New passwords can't equal previouslu used ones")
public boolean checkForNewPassword(List<String> prevPasswords, String password){
return !prevPasswords.contains(password);
}
}
/*注解处理器***************************************************/
package Ch20;
//import java.lang.reflect.Method;
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()){
//getAnnotation(Class)指定返回的注解类型的对象。没有返回null
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<>();
Collections.addAll(useCases,47,48,49,50);
trackUseCases(useCases,PasswordUtils.class);
}
}
/*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 previouslu used ones
Warning: Missing use case-50*/
20.2.1 注解元素
注解元素可用的类型如下:
所有基本类型 |
---|
String |
Class |
enum |
Annotation |
以上类型的数组 |
注解也可以嵌套
20.2.2 默认值限制
元素不能有不确定的值。
对于非基本类型的元素,不能以null作为其值。这个限制使得表现元素缺失或存在状态很难。
package Ch20;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
public int id() default -1;
public String description() default "";
}