今天这章节来讲讲Java里面的注解。
1. 基本概念
注解是JDK1.5引入的一个Java语言新特性。注解与接口很相似,它与类、接口、枚举是同一层次,它们都称为Java的一个类型(TYPE)。
注解:也称为元数据,为我们提供了程序代码的描述信息,而这些描述信息并不属于程序本身。注解并不直接影响其注释的代码的工作。是为了方便在后面某个时刻非常方便的使用这些数据。
注解:是一个包含注解类型和零或多个K-V对的Java修饰符。每中每个K-V对都绑定了一个不同的注解类型值。注解的目标简单的说就是绑定信息到其标注的编程元素。
注解的用途:
1)为编译器提供信息:注解可以被编译器用来检测错误与警告。像@Override这样的
2)编译时和部署时附加操作:比如说生成说明文档。
3)运行时操作:
像Junit从4.X开始使用注解简化测试代码和流程
Spring也会使用注解做XML配置管理的一种配合或替代
有些工具根据特定的注解做代码分析等
注解可以减少、美化代码,或为现有代码增加额外功能等。
4. 语法
注解的定义和接口定义相似,又有些不同。如:
无参注解
@Documented // 此注解包含在Javadoc中
@Retention(RetentionPolicy.RUNTIME) // VM运行期仍保留该注解,可通过反射获得
// 此注解适用的目标(构造方法、字段、本地变量、方法、包、参数、类型)
@Target(value = {ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.LOCAL_VARIABLE,ElementType.METHOD,ElementType.PACKAGE,ElementType.TYPE})
public @interface Deprecated {
// Deprecated 为注解名称
}
含参数注解
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.CONSTRUCTOR,ElementType.LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE) // 注解仅保留在Java源文件中
public @interface SuppressWarnings {
// 支持的参数列表all,deprecation,unchecked,path,finally等
String[] value();
}
自定义注解
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserCase {
// 测试用例编号
public int id();
/***
* 测试用例描述
* @return
*/
public String description() default "no desc";
}
最简单的注解
@interface Naked{}
允许子类继承父类的注解
@Inherited
public @interface TrustFather {
}
总结:
1、主题声明,权限修饰符 + @interface + 注解名称
2、注解描述
适用目标:@Target
保留级别:@Retention
是否产生JavaDoc: @Documented
允许子类继承父类的注解:@Inherited
其他注解
####以上我们是定义了注解,再看下要如何使用注解######
public class PasswordUtils {
@UserCase(id = 47, description = "密码必须至少有一个数")
public boolean validatePassword(String password) {
return password.matches("\\w*\\d\\w*");
}
@Deprecated
public void deprecatedMethod() {}
@SuppressWarnings({"unused", "rawtypes"})
public void unsafeMethod() {
List unsafeList = new ArrayList<String>();
}
}
如何让注解执行起来呢
public class UseCaseChecked {
public static void trackUseCases(List<Integer> useCases,Class<?> cl){
for (Method m:cl.getDeclaredMethods()
) {
UserCase uc = m.getAnnotation(UserCase.class);
if (uc!=null){
System.out.println("找到了一个用例:"+uc.id()+" " + uc.description());
useCases.remove(new Integer(uc.id()));
}
}
for (int i:useCases
) {
System.out.println("warn-没有用例:"+i);
}
}
public static void main(String[] args) {
List<Integer> useCases = new ArrayList<Integer>();
Collections.addAll(useCases,1,2,47);
trackUseCases(useCases,PasswordUtils.class);
}
}
以上通过反射的方式访问注解。
比如可以在这样用。定义在controller层上面的注解。然后在全局拦截器里面配置拦截。获取到是否有这样的注解。