注解是一种元数据形式
注解可以用来修饰类,包,方法,变量,参数
关键字@interface,所用的注解继承于 java.lang.annotation.Annotation接口
自定义类中只可以定义注解类型元素
public @interface CherryAnnotation {
public String name();
int age();
int[] array();
}
注解类元素注意以下几点
- 访问修改符必须public,不写默认
- 元素只能是基本数据类型
- default 代表默认值
常用的元注解
@Target 表示将注解定义在哪些java元素上面
public enum ElementType {
/** 类,接口(包括注解类型)或枚举的声明 */
TYPE,
/** 属性的声明 */
FIELD,
/** 方法的声明 */
METHOD,
/** 方法形式参数声明 */
PARAMETER,
/** 构造方法的声明 */
CONSTRUCTOR,
/** 局部变量声明 */
LOCAL_VARIABLE,
/** 注解类型声明 */
ANNOTATION_TYPE,
/** 包的声明 */
PACKAGE
}
@Retention 修饰注解的生命周期
public enum RetentionPolicy {
/**
* 注解将被编译器中丢弃
*/
SOURCE,
/**
* 注解在class文件中可用,但会被vm丢弃
*/
CLASS,
/**
* vm将在运行期间保留注解
*/
RUNTIME
}
@Documented注解
是被用来指定自定义注解是否能随着被定义的java文件生成到JavaDoc文档当中。
@Inherited
允许子类继承父类中的注解
写一个简单的注解类
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Annotations {
public String id();
public String description() default "no description";
}
/**
* Created by BaiCheng on 2019/7/1 18:20:13
*/
public class PasswordUtils {
@Annotations(id = "123",description = "备注")
public boolean validatePassword(String password){
return (password.matches("\\w*\\d\\w*")); //判断是否满足字符串给定的正则表达式
}
}
通过java反射获取注解
/**
* Created by BaiCheng on 2019/7/2 13:43:15
*/
@Resource
public class UserCaseTest {
public static void main(String[] args) {
List<Integer> useCases = new ArrayList<Integer>();
Collections.addAll(useCases, 47, 48, 49, 50);
trackUseCases(useCases, PasswordUtils.class);
}
public static void trackUseCases(List<Integer> useCases, Class<?> cl) {
//getDeclaredMethods() 获取本类中的所有方法 (只拿本类中的)
for (Method m : cl.getDeclaredMethods()) {
//方法是获取该元素上指定的注解。之后再调用该注解的注解类型元素方法就可以获得配置时的值数据;
Annotations uc = m.getAnnotation(Annotations.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);
}
}
}