1、注解
1.1 注解的定义
Java文件叫做Annotation,用@interface表示。
1.2 注解分类
注解大体上分为三种:标记注解,一般注解,元注解。
1.2.1 标记注解
@Override用于标识,该方法是继承自超类的。这样,当超类的方法修改后,实现类就可以直接看到了。
@Deprecated注解,则是标识当前方法或者类已经不推荐使用,如果用户还是要使用,会生成编译的警告。
@SuppressWarnings,抑制编译器发出特定警告。
1.2.2 一般注解
@Generated,标识计算机产生的源代码。
1.2.3 元注解
- @Documented 标记生成javadoc
- @Inherited 标记继承关系
- @Retention 注解的生存期
- @Target 标注的目标
1.3 注解的保留策略
- @Retention(RetentionPolicy.SOURCE) // 注解仅存在于源码中,在class字节码文件中不包含。
- @Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得。
- @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到。
1.4 作用目标
- @Target(ElementType.TYPE) // 接口、类、枚举、注解
- @Target(ElementType.FIELD) // 字段、枚举的常量
- @Target(ElementType.METHOD) // 方法
- @Target(ElementType.PARAMETER) // 方法参数
- @Target(ElementType.CONSTRUCTOR) // 构造函数
- @Target(ElementType.LOCAL_VARIABLE) // 局部变量
- @Target(ElementType.ANNOTATION_TYPE) // 注解
- @Target(ElementType.PACKAGE) // 包
2、java示例
2.1 自定义注解
/**
* 赋值
* @Title: Assign.java
* @Package com.spring.pro.annotation
* @Description:
* @author ybwei
* @date 2018年11月15日 下午4:55:51
* @version V1.0
*/
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Assign {
public String value() default "";
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Title: Validate.java
* @Package com.spring.pro.annotation
* @Description:校验
* @author ybwei
* @date 2018年11月15日 下午1:57:02
* @version V1.0
*/
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Validate {
/**
* 最小值
* @return
* @author ybwei
*/
public int min() default 1;
/**
* 最大值
* @return
* @author ybwei
*/
public int max() default 10;
}
2.2 定义使用注解实体
import com.spring.pro.annotation.Assign;
import com.spring.pro.annotation.Validate;
/**
* @Title: User.java
* @Package com.spring.pro.model
* @Description:
* @author ybwei
* @date 2018年11月15日 下午3:49:28
* @version V1.0
*/
public class Person {
@Assign(value = "张三")
private String name;
private String gender;
@Validate(min = 22, max = 50)
private Integer age;
public Person() {
super();
}
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
@Assign(value = "男")
public void setGender(String gender) {
this.gender = gender;
}
}
2.3 注解解析器
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.spring.pro.annotation.Assign;
/**
* @Title: ObjectFactory.java
* @Package com.spring.pro.factory
* @Description:
* @author ybwei
* @date 2018年11月15日 下午3:45:01
* @version V1.0
*/
public class ObjectFactory {
public static <T> T create(Class<T> clazz) throws Exception {
T obj = clazz.getConstructor(new Class[] {}).newInstance(new Object[] {});
// 获取T类中所有的方法(getDeclaredMethods也行)
Method[] methods = clazz.getMethods();
// 获取T类的所有属性(如果使用getFields,就无法获取到private的属性)
Field[] fields = clazz.getDeclaredFields();
for (Method method : methods) {
// 如果此方法有注解,就把注解里面的数据赋值到obj对象
if (method.isAnnotationPresent(Assign.class)) {
Assign assign = method.getAnnotation(Assign.class);
method.invoke(obj, assign.value());
}
}
for (Field field : fields) {
if (field.isAnnotationPresent(Assign.class)) {
Assign assign = field.getAnnotation(Assign.class);
field.setAccessible(true);
field.set(obj, assign.value());
}
}
return obj;
}
}
import java.lang.reflect.Field;
import com.spring.pro.annotation.Validate;
/**
* @Title: ObjectValidate.java
* @Package com.spring.pro.factory
* @Description:
* @author ybwei
* @date 2018年11月15日 下午3:52:48
* @version V1.0
*/
public class ObjectValidate {
public static <T> boolean validate(T obj) throws Exception {
// 获取T类的所有属性(如果使用getFields,就无法获取到private的属性)
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
// 如果属性有注解,就进行校验
if (field.isAnnotationPresent(Validate.class)) {
Validate validate = field.getAnnotation(Validate.class);
field.setAccessible(true);
Integer num = (Integer) field.get(obj);
if (num < validate.min()) {
System.out.println(field.getName() + "小于最小长度!!");
return false;
}
if (num > validate.max()) {
System.out.println(field.getName() + "大于最小长度!!");
return false;
}
}
}
return true;
}
}
2.4 测试
@Test
public void testObjectAssign() throws Exception {
Person person = ObjectFactory.create(Person.class);
System.out.println(person.getName());
System.out.println(person.getGender());
}
@Test
public void testObjectValidate() throws Exception {
Person person = new Person("李四",21);
System.out.println(ObjectValidate.validate(person));
}