通常,如果不是总是这样,我们将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)