必威体育Betway必威体育官网
当前位置:首页 > IT技术

Java中的注解 - @NotNull

时间:2019-08-06 00:13:11来源:IT技术作者:seo实验室小编阅读:56次「手机版」
 

notnull

比如说,你写了一个后台系统,接收用户的请求,经过运算后返回结果,很通用的一个实现方案。假定所有的方法都需要校验参数是否为空,不然就可能有NullPointerException,如果系统有N个接口,每个接口参数有M个,你需要写N * M个if判断语句。如

if (StringUtils.isBlank(request.getA())) {
    throw new illegalargumentException("A is blank");
}

这么写下来,肯定代码是很丑的。那怎么办呢?记得我们之前说过的编码理念,Don't repeat yourself,就派上用场了。

java中已经定义了@notnull注解,可以用来做这件事。(我们也可以自定义注解,见上一篇文章)在我们这个场景,我们的需求是:

  1. 在请求类中,所有不能为空的属性上,需要标记为@NotNull
  2. 写一个通用的validation方法,获取请求中的参数,检查如果有标记@NotNull,且参数的值为null,则抛出异常。

代码实现,

public class QueryUserRequest extends BaseRequest {
    @NotNull
    private String name;
    @NotNull
    private integer age;
    private Boolean gender;
    // 省略getter, setter方法
}

为了使校验参数的方法得到最大的通用性,我们把它放到BaseRequest中,让所有的request都继承这个父类。

public class BaseRequest {
    public void nullfieldValidate() throws IllegalAccessException, InvocationTargetException {
        Field[] fields = this.getClass().getDeclaredFields();
        for (Field field : fields) {
            String fieldName = field.getName();
            Object fieldValue = runGetter(field, this);

            boolean isAnnotationNotNull = field.isAnnotationPresent(NotNull.class);
            if (isAnnotationNotNull && fieldValue == null) {
                System.out.println(fieldName + " can't be null");
            }
        }
    }

    // 由于所有子类的属性都是private的,所以必须要找到属性的getter方法
    //  以下代码借鉴[stackoverflow的文章](https://stackoverflow.com/questions/13400075/reflection-generic-get-field-value)
    public Object runGetter(Field field, Object instance) {
        // MZ: Find the correct method
        for (Method method : instance.getClass().getDeclaredMethods()) {
            if ((method.getName().startsWith("get")) && (method.getName().length() == (field.getName().length() + 3))) {
                if (method.getName().toLowerCase().endsWith(field.getName().toLowerCase())) {
                    // MZ: Method found, run it
                    try {
                        return method.invoke(instance);
                    } catch (IllegalAccessException | InvocationTargetException e) {
                        System.out.println("Could not determine method: " + method.getName());
                    }
                }
            }
        }
        return null;
    }
}

对于获取类属性上的注解有3种方法,如果有其他的方法也可以告知

Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
    // 方法1
    Annotation[] annotations = field.getDeclaredAnnotations();
    for (Annotation annotation : annotations) {
        if (annotation instanceof NotNull && fieldValue == null) {
            System.out.println(field.getName() + " can't be null");
        }
    }
    // 方法2
    Annotation annotation = field.getAnnotation(NotNull.class);
    if (annotation != null && fieldValue == null) {
            System.out.println(field.getName() + " can't be null");
    }
    // 方法3
    boolean isAnnotationNotNull = field.isAnnotationPresent(NotNull.class);
    if (isAnnotationNotNull && fieldValue == null) {
            System.out.println(field.getName() + " can't be null");
    }
}

作者:rockops

链接:https://www.jianshu.com/p/a997d03d0cd6

相关阅读

使用@Autowired注解警告Field injection is not recom

在使用spring框架中的依赖注入注解@Autowired时,idea报了一个警告 大部分被警告的代码都是不严谨的地方,所以我深入了解了一下。 被

Spring Aop实例(AOP 如此简单)@Aspect、@Around 注解方

转载 ,原文博客地址 : https://www.jianshu.com/p/9517c90db0d4 运行工程 运行具有Main函数的 App.java得到如下输出 method star

需要在Transactional注解指定rollbackFor或者在方法中

需要在Transactional注解指定rollbackFor或者在方法中显示的rollback 芥末无疆sss 关注2018.02.14 01:53 字数 842 阅读 39评

JPA使用指南 javax.persistence的注解配置

转自http://67566894.iteye.com/blog/659829 @SuppressWarnings("serial") @Entity @Table(name="T_X") public class X impleme

关于Spring注解式事务@Transactional的简单描述

一、背景: 目前很多项目的事务处理都是利用Spring的注解式事务实现的(@Transactional)。 在测试事务回滚的过程中发现如下现象: t

分享到:

栏目导航

推荐阅读

热门阅读