java not null_Java中的注解 - @NotNull

可能大家看了我上一篇注解的文章,还是不知所云。这很正常,概念性的东西,不容易让大家有感性的认识。我认为最高效的学习方法,就是在实践中运用。我们拿@NotNull注解来举例。

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

if (StringUtils.isBlank(request.getA())) {

throw new IllegalArgumentException("A is blank");

}

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

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

在请求类中,所有不能为空的属性上,需要标记为@NotNull

写一个通用的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");

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值