java - 空检查链与捕获 NullPointerException

标签 java exception nullpointerexception null custom-error-handling

Web 服务返回一个巨大的 XML,我需要访问它的深层嵌套字段。例如:

return wsObject.getFoo().getBar().getBaz().getInt()

问题是getFoo()getBar()getBaz()可能都返回null .

但是,如果我在所有情况下都检查 null,代码会变得非常冗长且难以阅读。此外,我可能会错过某些字段的检查。

if (wsObject.getFoo() == null) return -1;
if (wsObject.getFoo().getBar() == null) return -1;
// maybe also do something with wsObject.getFoo().getBar()
if (wsObject.getFoo().getBar().getBaz() == null) return -1;
return wsObject.getFoo().getBar().getBaz().getInt();

可以写吗

try {
    return wsObject.getFoo().getBar().getBaz().getInt();
} catch (NullPointerException ignored) {
    return -1;
}

或者这会被视为反模式吗?

最佳答案

捕获 NullPointerException真正有问题的事情,因为它们几乎可以在任何地方发生。很容易从错误中得到一个,偶然发现它并继续,好像一切正​​常,从而隐藏一个真正的问题。 处理起来非常棘手,因此最好完全避免。(例如,考虑自动拆箱 null Integer。)

我建议您使用 Optional而是上课。当您想要处理存在或不存在的值时,这通常是最佳方法。

使用它,您可以像这样编写代码:

public Optional<Integer> m(Ws wsObject) {
    return Optional.ofNullable(wsObject.getFoo()) // Here you get Optional.empty() if the Foo is null
        .map(f -> f.getBar()) // Here you transform the optional or get empty if the Bar is null
        .map(b -> b.getBaz())
        .map(b -> b.getInt());
        // Add this if you want to return null instead of an empty optional if any is null
        // .orElse(null);
        // Or this if you want to throw an exception instead
        // .orElseThrow(SomeApplicationException::new);
}

为什么是可选的?

对可能不存在的值使用 Optionals 而不是 null 会使这一事实对读者来说非常明显和清晰,并且类型系统将确保您不会不小心忘记了。

您还可以更方便地访问使用这些值的方法,例如 maporElse .


缺勤是有效还是错误?

但还要考虑中间方法返回 null 是否是有效结果,或者这是否是错误的标志。如果它总是一个错误,那么抛出异常可能比返回一个特殊值更好,或者让中间方法本身抛出异常。


也许还有更多的选择?

另一方面,如果中间方法中的缺失值是有效的,也许您也可以为它们切换到 Optional s?

然后你可以像这样使用它们:

public Optional<Integer> mo(Ws wsObject) {
    return wsObject.getFoo()
        .flatMap(f -> f.getBar())
        .flatMap(b -> b.getBaz())
        .flatMap(b -> b.getInt());        
}

为什么不可选?

我能想到的不使用 Optional 的唯一原因是,这是否是代码中对性能非常关键的部分,并且如果垃圾收集开销被证明是一个问题。这是因为每次执行代码时都会分配一些 Optional 对象,而 VM 可能 无法优化这些对象。在这种情况下,您原来的 if 测试可能会更好。

关于java - 空检查链与捕获 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37960674/

相关文章:

java - Google App Engine-如何改善冷启动JVM时间?

java - java 8中从父类(super class)继承方法而不是从实现接口(interface)继承默认方法的意义

java - WHILE 循环条件不验证输入

java - 异常和parseInt

groovy - 编译时使用groovy方法进行NPE

java - 如何通过在android中创建类的实例来执行onCreate方法

java - 在 JTable 中搜索通过 JTextField 数据输入的数据

java - Apache Spark,创建配置单元上下文 - NoSuchMethodException

java - Eclipse 建议空指针异常,但我相信我初始化了我的对象

android - 获取屏幕截图时出现意外错误 - java.lang.nullpointerexception