Java中的注解2_自定义注解实现非空判断

注解的基本知识看这里:

Java中的注解1_自定义注解

1.项目结构如下

image-20210425221210761

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

在5测试类里面可以看到,这个YangNotNullExplain的validate方法是被主动调用的.

在框架里面,会用其它的代码来自动触发这一动作,如aop.

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()
posted @ 2021-04-25 22:15  羊37  阅读(1694)  评论(0编辑  收藏  举报