Lombok之@NonNull使用

x33g5p2x  于2021-12-25 转载在 其他  
字(2.1k)|赞(0)|评价(0)|浏览(532)

一. 为什么要用@NonNull?

NullPointerException空指针异常(俗称NPE异常)可以说是每一个开发者都遇到过的一个常见异常,即使是经验丰富的老手,也会在一不留神的写出NPE的bug。指针只存在于c语言中,Java中是没有指针的,空指针就是空引用,java空指针异常就是引用本身为空,却调用了方法,这个时候就会出现空指针异常。可以理解,成员变量和方法是属于对象的(除去静态),在对象中才存在相对应的成员变量和方法,然后通过对象去调用这些成员变量和方法。对于空指针来说,它不指向任何对象,也就没有所谓的成员变量和方法,这个时候用它去调用某些属性和方法,当然会出现空指针异常。
新建Student类,并创建全参构造函数,getter和setter方法。

public class Student {

    private String name;

    private Integer age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

我们new了一个name为null,age为18的student对象。可以看到当程序通过student.getName()访问name变量后,再调用String的实例方法length(),控制台抛出了NullPointerException异常。这是因为name的变量值为null,所以报NPE异常。解决这类问题的办法,我们可以在取出name值后进行判空操作,但是这样每次取name值都要进行判空操作,很是麻烦。我们可以在构造函数中要求name值非空:

public Student(String name, Integer age) {
        if (name == null) {
            throw new NullPointerException("name is null");
        } else {
            this.name = name;
            this.age = age;
        }
    }

这样一来,我们在new的时候就会提前发现错误。new的时候就会报NullPointerException,避免后面的空指针异常。new时候的空指针异常是不可能避免的,这是由于Java中规定null可以为任何包装类型的变量赋值。这个判空的逻辑体可以使用Lombok的注解@NonNull进行简化代码。

二. @NonNull如何使用?

在个构造函数的参数加上@NonNull后,便会自动对该参数值进行判空。

public Student(@NonNull String name, Integer age) {
        this.name = name;
        this.age = age;
    }

编译该工程,打开编译后的文件。可以看到,编译器已经为形参name生成了判空的代码。

三. @NonNull源码

package lombok;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/** * If put on a parameter, lombok will insert a null-check at the start of the method / constructor's body, throwing a * {@code NullPointerException} with the parameter's name as message. If put on a field, any generated method assigning * a value to this field will also produce these null-checks. * 如果放在一个参数上,lombok将在方法/构造函数体的开头插入一个空检查,抛出一个{@code NullPointerException},参数名为message。如果放 * 在字段(成员变量)上,则生成的任何方法都被赋值该字段的值也将产生这些空值检查。 */
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
@Retention(RetentionPolicy.CLASS)
@Documented
public @interface NonNull {
}

四. 特别说明

本文已经收录在Lombok注解系列文章总览中,并继承上文中所提的特别说明。
源码地址:gitee

相关文章