Java如何检查对象引用是否不为null?

通常,如果不是总是这样,我们将if语句与==or!=运算符结合使用,以检查对象引用是否为null。我们这样做是为了验证传递给构造函数或方法的参数不包含空值。这些空检查在我们的代码中可以看作是混乱的。

解决的办法是使用java.util.Objects类。静态实用程序类提供了requireNonNull(T)和类似的方法,requireNonNull(T, String)以检查指定的对象引用是否不为null。如果为null,则这些方法将引发NullPointerException。使用第二种方法变体,我们可以自定义异常消息。

下面的示例显示了我们如何使用这些方法。

package org.nhooo.example.util;

import java.util.Objects;

public class ObjectsNullCheckDemo {
    private String firstName;
    private String lastName;

    /**
     * Validate constructor arguments. The firstName and lastName 
     * arguments can't be null. A NullPointerException with the 
     * specified message will be thrown.
     */
    public ObjectsNullCheckDemo(String firstName, String lastName) {
        this.firstName = Objects.requireNonNull(firstName, 
                "First name can't be null.");
        this.lastName = Objects.requireNonNull(lastName, 
                "Last name can't be null.");
    }

    public void setFirstName(String firstName) {
        // 名不能为空。
        this.firstName = Objects.requireNonNull(firstName,
                "First name can't be null.");
    }

    public void setLastName(String lastName) {
        // 姓氏不能为空。
        this.lastName = Objects.requireNonNull(lastName,
                "Last name can't be null.");
    }

    public static void main(String[] args) {
        // 这条线很好。
        ObjectsNullCheckDemo demo = new ObjectsNullCheckDemo("John", "Doe");
        System.out.println("demo = " + demo);

        try {
            // 该行产生一个NullPointerException
            ObjectsNullCheckDemo demo1 = new ObjectsNullCheckDemo("Alice", null);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String name = null;
        try {
            // 下面的行将抛出java.lang.NullPointerException。
            Objects.requireNonNull(name);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public String toString() {
        return "ObjectsNullCheckDemo{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                '}';
    }
}

运行上面的代码将打印以下结果:

demo = ObjectsNullCheckDemo{firstName='John', lastName='Doe'}
java.lang.NullPointerException: Last name can't be null.
    at java.util.Objects.requireNonNull(Objects.java:228)
    at org.nhooo.example.util.ObjectsNullCheckDemo.<init>(ObjectsNullCheckDemo.java:14)
    at org.nhooo.example.util.ObjectsNullCheckDemo.main(ObjectsNullCheckDemo.java:34)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
java.lang.NullPointerException
    at java.util.Objects.requireNonNull(Objects.java:203)
    at org.nhooo.example.util.ObjectsNullCheckDemo.main(ObjectsNullCheckDemo.java:42)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)