使用if语句与异常处理检查空值

时间:2016-03-29 23:32:29

标签: java

String s = foo.getBar().getFrobz().getNobz().getBaz();

我想返回getBaz()的值。问题是,任何其他方法都可能返回null - 在这种情况下,我只想返回一个空字符串。

以下是实现此效果的一种方法:

String s = "";

if (foo.getBar() != null ) {
    if (foo.getBar().getFrobz() != null) {
        if (foo.getBar().getFrobz().getNobz() != null) {
            if (foo.getBar().getFrobz().getNobz().getBaz() != null) {
                s = foo.getBar().getFrobz().getNobz().getBaz();
            }
        }
    }
}

这是另一种更简单的方法:

String s = "";

try {
    s = foo.getBar().getFrobz().getNobz().getBaz();
} catch (NullPointerException npe) {

}

我听说异常比if语句贵,但看起来更干净。也许这个问题可以通过另一种方式解决?任何帮助表示赞赏。

6 个答案:

答案 0 :(得分:1)

如何使用Optional课程?它是为这种情况创建的。您可以像这样使用它:

return Optional.ofNullable(foo.getBar());

if(optional.isPresent()) {
    // do something with the value
}

请注意,这仅适用于Java 8.除了使用值null之外,我们强烈建议不要这样做。如果Exception值存在问题,最好使用null

请注意,foo.getBar().getFrobz().getNobz().getBaz()在清洁代码方面被称为“火车残骸”。你应该避免暴露像这样的对象的内部。

以下程序将打印“不存在”:

public class Main {

    public static void main(String[] args) {
        Foo foo = new Foo();

        final Optional<String> s = foo.getBar()
                .flatMap(Bar::getFrobz)
                .flatMap(Frobz::getNobz)
                .flatMap(Nobz::getBaz);
        if(s.isPresent()) {
            System.out.println("present");
        } else {
            System.out.println("not present");
        }
    }

    private static class Foo {
        Bar bar;

        public Optional<Bar> getBar() {
            return ofNullable(bar);
        }
    }

    private static class Bar {
        Frobz frobz;

        public Optional<Frobz> getFrobz() {
            return ofNullable(frobz);
        }
    }

    private static class Frobz {
        Nobz nobz;

        public Optional<Nobz> getNobz() {
            return ofNullable(nobz);
        }
    }

    private static class Nobz {
        String baz;

        public Optional<String> getBaz() {
            return ofNullable(baz);
        }
    }
}

还有null object pattern在这种情况下可以派上用场。

答案 1 :(得分:0)

就个人而言,我想避开链并让每个调用者负责给我一个合理的返回值,然后我可以在一个方法中使用。

所以,我会这样称呼你的方法:

foo.getBar();

...并且在bar内部,我将有逻辑来处理依赖方法的场景,即null

public String getBar() {
    String result = getFrobz();
    return result == null ? "" : result;
}

当然,这导致了一种不同类型的链,但是这使得您可以更精细地控制每个返回值应该是什么,而不是祈祷您得到的返回结果之一不是null

答案 2 :(得分:0)

这是一种我认为更优雅的方式:

Bar bar;
Frobz frobz;
Nobz nobz;
String baz;
if (null != (bar = foo.getBar()) &&
    null != (frobz = bar.getFrobz()) &&
    null != (nobz = frobz.getNobz()) &&
    null != (baz = nobz.getBaz())) {
    s = baz;
}

答案 3 :(得分:0)

这是基于Adam Arold的简洁完整解决方案:

String s = Optional.ofNullable(foo.getBar())
        .map(Bar::getFrobz)
        .map(Frobz::getNobz)
        .map(Nobz::getBaz)
        .orElse("");

答案 4 :(得分:0)

这里的正确答案是使用嵌套的if条件。没有其他好的解决方案,并且使用异常并不是一个好主意,因为我不是在尝试处理异常 - 我只是想分配一个值。

答案 5 :(得分:-2)

重要的是要注意上面的两个方块不相同。异常处理将捕获NPE抛出 通过调用链中的方法抛出的getters NPE,其中null结果为嵌套ifs仅处理后者。

由于他们做了不同的事情,他们服务于不同的用例。只有当你想要一个空字符串时才能捕获异常,无论NPE来自何处,否则使用嵌套的if。其他人为您提供了减少深度筑巢的方法。