注解也称为元数据,使用注解可以给代码增加额外信息,在某个时刻可以非常方便的使用这些信息
定义
注解也称为元数据,使用注解可以给代码增加额外信息,在某个时刻可以非常方便的使用这些信息
标准注解
注解 | 含义 |
---|---|
@Override | 表示当前方法会覆盖超类的方法 |
@Deprecated | 当使用了被它注解的元素时,编译器会发出警告(过时方法) |
@SuppressWarinnings | 关闭不当的编译器警告 |
元注解
@Target
表示注解可以用到哪些地方,可能的ElementTyoe参数
类型 | 含义 |
---|---|
TYPE | 类,接口(包括注释类型),或枚举 |
FIELD | 字段(包括枚举常数) |
METHOD | 方法 |
PARAMETER | 方法参数 |
CONSTRUCTOR | 构造函数 |
LOCAL_VARIABLE | 局部变量 |
PACKAGE | 包 |
ANNOTATION_TYPE | 注释类型 |
TYPE_PARAMETER | 类型参数 |
TYPE_USE | 使用的类型 |
@Retention
注解保留策略
类型 | 含义 |
---|---|
SOURCE | 注解会被编译器丢弃 |
CLASS | 注解在class文件中可用,但是会被虚拟机丢弃 |
RUNTIME | 使用的最多的策略 在虚拟机运行期依然保留,可以通过反射获取注解信息 |
@Documented
将此注解包含在javadoc中
@Inherited
允许子类继承父类的注解
@Native
指定字段是一个常量,引用native code
@Repeatable
指定字段是一个常量,引用native code
注解的元素(属性)
没有属性的注解被称为标记注解,只用来给代码做标记
元素(属性)的类型
- 八个基本类型:char、boolean、byte、short、int、long、float、double、
- String
- Class
- enum
- Annotation
- 以及上述类型的数组
元素(属性)默认值
编译器对元素(属性)的默认值非常的严格。
元素(属性)必须是确定的值。
是默认值或者是使用注解时提供的元素(属性)值
自定义注解
除了@符号之外,注解的定义和接口很像。定义注解时,需要一些元注解,来声明注解的使用范围和保留策略
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
public int id() default -1;
public String description() default "";
}
public class PasswordUtils {
@UseCase(id=1,description = "密码必须至少包含一个数字")
public boolean validatePassword(String password){
return (password.matches("\\w*\\d\\w*"));
}
@UseCase()
public String encryptPassword(String password){
return new StringBuilder(password).reverse().toString();
}
@UseCase(id=3,description = "新密码不能是原密码")
public boolean checkForNewPassword(String oldPassword,String newPassword){
return oldPassword.equals(newPassword);
}
}
注解处理器
public class UserCaseTracker {
public static void trackUserCase(List<Integer> userCase,Class<?> c){
for (Method m : c.getDeclaredMethods()) {
UseCase uc = m.getAnnotation(UseCase.class);
if(uc != null){
System.out.println("找到用例:" + uc.id() + " " + uc.description());
userCase.remove(new Integer(uc.id()));
}
}
for (Integer i : userCase) {
System.out.println("警告: 缺少用例 - " + i );
}
}
public static void main(String[] args) {
List<Integer> useCases = new ArrayList<Integer>();
Collections.addAll(useCases,1,2,3,4,5,6,7);
trackUserCase(useCases, PasswordUtils.class);
}
}