我使用x!=null以避免NullPointerException。还有其他选择吗?

if (x != null) {
    // ...
}

当前回答

对于Java8或更新版本,最好的选择可能是使用Optional类。

Optional stringToUse = Optional.of("optional is there");
stringToUse.ifPresent(System.out::println);

这对于可能的空值的长链来说尤其方便。例子:

Optional<Integer> i = Optional.ofNullable(wsObject.getFoo())
    .map(f -> f.getBar())
    .map(b -> b.getBaz())
    .map(b -> b.getInt());

如何在null上引发异常的示例:

Optional optionalCarNull = Optional.ofNullable(someNull);
optionalCarNull.orElseThrow(IllegalStateException::new);

Java7引入了Objects.requireOnNull方法,当需要检查某些内容是否为非空时,该方法非常方便。例子:

String lowerVal = Objects.requireNonNull(someVar, "input cannot be null or empty").toLowerCase();

其他回答

Java8带来了新的Java.util.Optional类,它可以解决一些问题。至少可以说,它提高了代码的可读性,并且在公共API的情况下,使API的契约对客户端开发人员更加清晰。

它们是这样工作的:

给定类型(Fruit)的可选对象被创建为方法的返回类型。它可以是空的或包含Fruit对象:

public static Optional<Fruit> find(String name, List<Fruit> fruits) {
   for (Fruit fruit : fruits) {
      if (fruit.getName().equals(name)) {
         return Optional.of(fruit);
      }
   }
   return Optional.empty();
}

现在看看这段代码,我们在其中搜索给定Fruit实例的Fruit(水果)列表:

Optional<Fruit> found = find("lemon", fruits);
if (found.isPresent()) {
   Fruit fruit = found.get();
   String name = fruit.getName();
}

您可以使用map()运算符对可选对象执行计算,或从中提取值。orElse()允许您为缺少的值提供回退。

String nameOrNull = find("lemon", fruits)
    .map(f -> f.getName())
    .orElse("empty-name");

当然,检查空/空值仍然是必要的,但至少开发人员意识到该值可能是空的,忘记检查的风险是有限的。

在从头开始使用Optional构建的API中,只要返回值可能为空,并且仅在不能为空时返回纯对象(惯例),客户端代码可能会放弃对简单对象返回值的空检查。。。

当然,Optional也可以用作方法参数,在某些情况下,可能比5或10个重载方法更好地指示可选参数。

可选提供了其他方便的方法,例如允许使用默认值的orElse,以及与lambda表达式一起使用的ifPresent。

我邀请您阅读这篇文章(我撰写这个答案的主要来源),其中很好地解释了NullPointerException(以及一般的空指针)问题以及Optional带来的(部分)解决方案:Java Optional Objects。

函数方法可能有助于包装重复的空检查并执行匿名代码,如下面的示例。

    BiConsumer<Object, Consumer<Object>> consumeIfPresent  = (s,f) ->{
        if(s!=null) {
            f.accept(s);
        }
    };

    consumeIfPresent.accept(null, (s)-> System.out.println(s) );
    consumeIfPresent.accept("test", (s)-> System.out.println(s));

    BiFunction<Object, Function<Object,Object>,Object> executeIfPresent  = (a,b) ->{
        if(a!=null) {
            return b.apply(a);
        }
        return null;
    };
    executeIfPresent.apply(null, (s)-> {System.out.println(s);return s;} );
    executeIfPresent.apply("test", (s)-> {System.out.println(s);return s;} );

你有一个选择

在方法上使用checker框架的@RequiresNonNull。对于ex,如果使用null参数调用一个注释为null的方法,就会得到这个结果。它将在编译期间失败,甚至在代码运行之前!因为在运行时它将是NullPointerException@RequiresNonNull(值={“#1”})静态空隙检查(布尔x){如果(x)System.out.println(“true”);else System.out.println(“false”);}公共静态void main(String[]参数){检查(空);}

得到

[ERROR] found   : null
[ERROR] required: @Initialized @NonNull Boolean
[ERROR] -> [Help 1]

还有其他方法,如Use Java 8‘s Optional、Guava Annotations、Null Object pattern等。只要您达到避免的目标,就无所谓了=无效的

Java8在Java.util包中引入了一个新的类Optional。

Java 8的优点可选:

1.)不需要空检查。2.)运行时不再出现NullPointerException。3.)我们可以开发干净整洁的API。

可选-可以包含或不包含非空值的容器对象。如果存在值,isPresent()将返回true,而get()则返回该值。

有关更多详细信息,请在此处找到oracle文档:-https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html

您可以使用类似JUnit的框架将类与单元测试相结合。这样,您的代码将是干净的(没有无用的检查),并且您将确保您的实例不会为空。

这是使用单元测试的一个很好的理由。