Java中的注解 – @NotNull「建议收藏」

Java中的注解 – @NotNull「建议收藏」比如说,你写了一个后台系统,接收用户的请求,经过运算后返回结果,很通用的一个实现方案。假定所有的方法都需要校验参数是否为空,不然就可能有NullPointerException,如果系统有N个接口,每个接口参数有M个,你需要写N*M个if判断语句。如if(StringUtils.isBlank(request.getA())){thrownewIllegalArgume…

大家好,又见面了,我是你们的朋友全栈君。

比如说,你写了一个后台系统,接收用户的请求,经过运算后返回结果,很通用的一个实现方案。假定所有的方法都需要校验参数是否为空,不然就可能有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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/138674.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • (图文)最详细的XAMPP的安装及使用教程「建议收藏」

    (图文)最详细的XAMPP的安装及使用教程「建议收藏」XAMPP的安装及使用教程1、简介2、安装运行3、配置数据库XAMPP的安装及使用教程1、简介XAMPP(Apache+MySQL+PHP+PERL)是一个功能强大的建站集成软件包。这个软件包原来的名字是LAMPP,但是为了避免误解,最新的几个版本就改名为XAMPP了。它可以在Windows、Linux、Solaris、MacOSX…

  • java定义数组变量初始化为0_java中怎么数组初始化?

    java定义数组变量初始化为0_java中怎么数组初始化?展开全部//数组定义最方便的就是用for循环来做定义,数组下标是从e69da5e6ba9062616964757a686964616f313333656462620开始,到11的话就是12个数字。要输出的话可以用以//号注释掉的后面的一句if(i<12){System.out.println(x[i]);}当然也可以自己再写一个for循环语句来输出,不过我觉得这有点画蛇添足了publicc…

  • 黑盒测试用例测试方法

    黑盒测试用例测试方法黑盒测试用例设计方法一、等价类划分法等价类划分法是一种典型的、重要的黑盒测试方法,是指某个输入域的子集合。在该子集合中,所有的输入数据对于揭露软件中的错误都是等效的。等价类划分有效等价类和无效等价类例如:微信红包的例子【0.01-200】按数据范围划分:有效的:0.01-200(1)无效的:小于0.01(2)…

  • 数字签名由数字摘要和对称加密技术组成_为何对称加密不适用于数字签名

    数字签名由数字摘要和对称加密技术组成_为何对称加密不适用于数字签名一个小故事让您轻松读懂,信息摘要、数字签名、数字证书、对称非对称加密

    2022年10月17日
  • 网口转串口线(console线)制作「建议收藏」

    网口转串口线(console线)制作「建议收藏」console线RJ45转串口9孔:短距离使用时连接RXD、TXD、GND线即可。

  • Elasticsearch学习,请先看这一篇!

    题记:Elasticsearch研究有一段时间了,现特将Elasticsearch相关核心知识、原理从初学者认知、学习的角度,从以下9个方面进行详细梳理。欢迎讨论……0.带着问题上路——ES是如何产生的?(1)思考:大规模数据如何检索?如:当系统数据量上了10亿、100亿条的时候,我们在做系统架构的时候通常会从以下角度去考虑问题:1)用什么数据库好?(mysql、sybase、oracle、达

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号