注解(元数据)为我们在代码中添加信息提供一种形式化的方法,我们可以在某个时刻非常方便的使用这些数据。将的通俗一点,就是为这个方法增加的说明或功能。例如:@Overvide这个注解就用来说明这个方式重写父类的。
Java目前内置了三种注解@Override、@Deprecated、@SuppressWarnnings
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
Java提供了四种元注解,即修饰注解的注解。观察上面源码可以发现三种,即:@Target、@Retention、@Document、@Inherited。主要作用如下:
使用@interface定义注解,会自动继承java.lang.annotation.Annotation接口,类似于类自动继承Object一样。注解中的每个方法表示一个配置参数,返回类型即是参数类型,可以通过default标识参数默认值。定义方式如下:
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
public @interface Test {
String value() default "";
}
注解中的参数只支持如下类型:
如果定义其他类型的参数编译器会报错。
如果没有读取注解的方法,那么该注解就没有任何意义。使用注解的过程中,注解处理器是必不可少的,Java领反射机制,完成对注解的处理 。
Java通过反射机制获取类、方法、属性上的注解,因此java.lang.reflect提供AnnotationElement支持注解,主要方法如下:
以下是注解实例:
定义注解:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
int max() default 0;
int min() default 0;
String description() default "";
}
注解使用:
public class AnnoationTest {
@Test(min = 6,max = 10,description = "用户名长度在6-10个字符之间")
private String name;
@Test(min = 6,max =10,description = "密码长度在6-10个字符之间")
private String pasdword;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPasdword() {
return pasdword;
}
public void setPasdword(String pasdword) {
this.pasdword = pasdword;
}
}
注解处理器以及测试主方法:
import java.lang.reflect.Field;
public class TestUtil {
public static void valid(Object obj) throws IllegalAccessException {
Class> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field:fields){
Test test = field.getAnnotation(Test.class);//获取属性上的@Test注解
if(test != null){
field.setAccessible(true);//设置属性可访问
if("class java.lang.String".equals(field.getGenericType().toString())){//字符串类型的才判断长度
String value = (String)field.get(obj);
if(value != null && ((value.length() > test.max()) || value.length() < test.min())){
System.out.println(test.description());
}
}
}
}
}
public static void main(String[] args){
AnnoationTest annotation = new AnnoationTest();
annotation.setName("abcefg");
annotation.setPasdword("1234567890");
try {
valid(annotation);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
会根据用户设置属性长度检查属性值是否符合要求