1.项目结构如下
2.YangNotNull
package cn.yang37.annotation.p20210425;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Description: 自定义注解 实现非空判断
* @Author: Yiang37
* @Date: 2021/04/25 21:45:45
* @Version: 1.0
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface YangNotNull {
String value();
}
3.YangNotNullExplain
package cn.yang37.annotation.p20210425;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* @Description:
* @Class: YangNotNullExplain
* @Author: Yiang37
* @Date: 2021/4/25 21:47
* @Version: 1.0
*/
public class YangNotNullExplain {
public static <T> List<String> validate(T t) throws IllegalAccessException {
// 结果list
ArrayList<String> resList = new ArrayList<>();
// 获取入参类t中的Field,可以理解为Filed为一个字段对象,会包含字段名,字段类型等属性.
Field[] declaredFields = t.getClass().getDeclaredFields();
for (Field declaredField : declaredFields) {
if (declaredField.isAnnotationPresent(YangNotNull.class)) {
// 反射获取的字段值 设置不检查访问权限
declaredField.setAccessible(true);
Object value = declaredField.get(t);
if (value == null) {
resList.add(declaredField.getAnnotation(YangNotNull.class).value() + " :不能为空!");
}
}
}
return resList;
}
}
4.User
package cn.yang37.annotation.p20210425;
import com.alibaba.fastjson.JSON;
import lombok.Data;
/**
* @Description:
* @Class: User
* @Author: Yiang37
* @Date: 2021/4/25 21:56
* @Version: 1.0
*/
@Data
public class User {
@YangNotNull("特意声明这是username字段上注解的值")
private String username;
@YangNotNull("特意声明这是age字段上注解的值")
private int age;
@YangNotNull("特意声明这是sex字段上注解的值")
private String sex;
@Override
public String toString() {
return JSON.toJSONString(this,true);
}
}
5.UserTest
package cn.yang37.annotation.p20210425;
import java.util.List;
/**
* @Description:
* @Class: UserTest
* @Author: Yiang37
* @Date: 2021/4/25 21:59
* @Version: 1.0
*/
public class UserTest {
public static void main(String[] args) throws IllegalAccessException {
// 注意初始化时String默认为null, 即user -> {"age":0}
User user = new User();
System.out.println(user.toString());
// 获取校验结果
List<String> validateList = YangNotNullExplain.validate(user);
validateList.forEach(System.out::println);
}
}
结果
{
"age":0
}
特意声明这是username字段上注解的值 : 不能为空!
特意声明这是sex字段上注解的值 : 不能为空!
6.扩展:方法说明
要有区分字段值和注解值的意识
6.1 getDeclaredFields()
返回Class中所有的字段,包括私有字段.
getFields(): 只返回公有字段
6.2 java.lang.reflect.Field.get(Object obj)
返回指定对象上由此Field表示的字段的值.
// declaredField字段在t对象中的实际值
Object value = declaredField.get(t);
6.3 isAnnotationPresent(Class<? extends Annotation> annotationClass)
对象上是否有该注解
// declaredField上是否有注解@YangNotNull
declaredField.isAnnotationPresent(YangNotNull.class);
6.4 getAnnotation(Class< A > annotationClass) 方法返回该元素的指定类型的注释
获取对象上的该注解
// declaredField上@YangNotNull注解的注解实际值
declaredField.getAnnotation(YangNotNull.class).value()