注解(也被称为元数据),为我么在代码中添加信息提供了一种形式化的方法,使得我们可以在稍后某个时刻可以非常方便的使用这些数据。
为什么要使用注解 ??
通过使用注解,我们可以将元数据保存在Java源代码中,并利用annotation API为自己的注解构造处理工具,,同时,注解还有使得代码更加干净易读,以及编译器类型检查等优点。
Java中有哪些内置的注解??
Java中内置了三种标准注解,以及四种元注解。
标准注解
- @Override 表示当前的方法将覆盖父类中的方法。
- @Deprecated 如果程序员使用了此注解,那么编译器会发出警告信息。
- @SuppressWarnings 关闭不当的编译器警告信息。
元注解 专门负责注解其他的注解
- @Target 表示注解可以用于什么地方。可能的 ElementType参数为:CONSTRUCTOR(构造器),FIELD(域),LOACAL_VARIABLE(局部变量),METHOD(方法),PACKAGE(包),PARAMETER(参数),TYPE(类,接口)
- @Retention 表示需要在什么级别保存该注解信息。 RetentionPolicy参数:SOURCE(注解将被编译器丢弃),CLASS(注解在class文件中可以使用,但会被VM丢弃),RUNTIME(VM也在运行期间也保留注解,因此可以通过反射机制读取注解的信息)。
- @Documented 将此注解包含在Javadoc中。
- @Inherited 允许子类继承父类中的注解。
下面我们通过一个例子,去看注解是如何使用的。
定义注解
package annotationdemo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 定义注解
* @author nxiangbo
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
public int id();
public String description() default "no description";
}
在类中使用注解
package annotationdemo;
import java.util.List;
public class PasswordUtils {
@UseCase(id = 47,description = "密码必须包含一位数字")
public boolean validatePassword(String pwd){
return pwd.matches("\\w*\\d\\w*");
}
@UseCase(id = 48)
public String encrptyPassword(String pwd){
return new StringBuilder(pwd).reverse().toString();
}
@UseCase(id = 49,description = "新的密码不能与旧的密码一样")
public boolean checkForNewPassword(List<String> prePwd,String pwd){
return !prePwd.contains(pwd);
}
}
注解处理器
如果没有读取注解的工具,那么注解也没什么大不了的。所以,很关键的是,要会创建注解处理器。
package annotationdemo;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 注解处理器
* @author nxiangbo
*
*/
public class UseCaseTracker {
public static void trackUseCase(List<Integer> useCases, Class<?> cl){
for (Method m : cl.getDeclaredMethods()) {
UseCase uc = m.getAnnotation(UseCase.class);
if(uc!=null){
System.out.println("UseCase: id = "+uc.id()+", description = "+uc.description());
useCases.remove(new Integer(uc.id()));
}
}
for (int i : useCases) {
System.out.println("Warning: Missing the useCase "+i);
}
}
public static void main(String[] args) {
List<Integer> useCases = new ArrayList<Integer>();
Collections.addAll(useCases, 47,48,49,50);
trackUseCase(useCases, PasswordUtils.class);
}
}