说道注解,其实之前一直都是不了解,也没想过去深探其原理(其实这篇也谈不上注解的原理 ^^),只是在年后的春天在一家公司实习做spring工作,各种注解铺天盖地,然而想了解,最后还是一知半解,其最后还是没有达到一个目的:什么时候使用自定义的注解,这是一个想了解学习注解同学最关心的问题,下面通过一个小例子来回答这个问题。
简单介绍一些常用的两个元注解,所谓元注解,就是用来修饰注解的注解
@Target 表示该注解可以用于什么地方,可能的ElementType参数有:
- CONSTRUCTOR:构造器的声明
- FIELD:域声明(包括enum实例)
- LOCAL_VARIABLE:局部变量声明
- METHOD:方法声明
- PACKAGE:包声明
- PARAMETER:参数声明
- TYPE:类、接口(包括注解类型)或enum声明
@Retention 表示需要在什么级别保存该注解信息。
- SOURCE:注解将被编译器丢弃
- CLASS:注解在class文件中可用,但会被VM丢弃
- RUNTIME:VM将在运行期间保留注解(最常用的一种)
先来使用Target为Filed的注解
注解的定义方式是使用@interface关键字申明
定义一个名为FruitName 的注解,根据Target的值为FIELD,可以知道该注解是修饰类中变量的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FruitName {
public String name() default "no fruit";
}
定义一个Apple类使用上面使用到的注解
public class Apple {
@FruitName(name="apple")
private String name;
// @FruitName(name="name1")
private String name1;
}
最后在main函数中去测试注解,使用到了Java反射知识,后续对Java反射做一个简单的整理
Class clazz = Apple.class;
Field[] cField = clazz.getDeclaredFields();
for (Field field : cField) {
FruitName fruitName = field.getAnnotation(FruitName.class);
if (fruitName != null) {
System.out.println(fruitName.name());
}
}
输出结果为 apple
下面对一个应用注解的场景做一个介绍,这个场景为权限管理,达到的目的是能够管理三种权限,分别是超级管理员admin,用户user以及拒绝访问的三种权限,使用的注解target为methord,使用的思想是根据用户的id去判断
47:admin
48:user
其他:拒绝访问
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UseCase {
public String description() default "no right";
public int id() default -1;
}
定义一个验证用户身份的类
public class UserCheckUtil {
@UseCase(id = 47 , description = "admin")
public String validatePassword(String password) {
return "admin";
}
@UseCase(id = 48, description = "user")
public String encryptPassword(String password) {
return "user";
}
}
下面是测试main函数
int result = trackUseCases(48, UserCheckUtil.class);
if (result == 1) {
System.out.println("admin");
}else if (result == 2) {
System.out.println("user");
}else {
System.out.println("no id");
}
其中trackUseCases函数为:
public static int trackUseCases(int useCases, Class<?> cl) {
for (Method m : cl.getDeclaredMethods()) {
UseCase uc = m.getAnnotation(UseCase.class);
if (uc != null && useCases == uc.id()) {
System.out.println("Found Use Case:" + uc.id() + " "
+ uc.description());
if (uc.description().equals("admin")) {
return 1;
} else if (uc.description().equals("user")) {
return 2;
}
}
}
return -1;
}
int result = trackUseCases(48, UserCheckUtil.class);
测试结果是
Found Use Case:48 user
user
int result = trackUseCases(47, UserCheckUtil.class);
测试结果是
Found Use Case:47 admin
admin
int result = trackUseCases(49, UserCheckUtil.class);
测试结果是
no id