Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 利用try-catch块而不是重复执行空检查_Java_Null_Dereference_Object Oriented Analysis - Fatal编程技术网

Java 利用try-catch块而不是重复执行空检查

Java 利用try-catch块而不是重复执行空检查,java,null,dereference,object-oriented-analysis,Java,Null,Dereference,Object Oriented Analysis,我正在考虑从今天的代码中删除不必要的null条件检查,这些检查主要涉及深嵌套对象。 例如: 我有一个类Big,它引用了Small对象及其getter和setter,同样Small也引用了 Tiny对象及其getter和setter和Tiny对象具有tinyleength变量,该变量是整数变量 例如,如果我正在编写一个方法,它接受一个Big对象参数,并在最后返回tinyleength,我通常会做一些事情 像这样: public Integer getTinyLength (Big big) {

我正在考虑从今天的代码中删除不必要的
null
条件检查,这些检查主要涉及深嵌套对象。 例如:

我有一个类
Big
,它引用了
Small
对象及其getter和setter,同样
Small
也引用了
Tiny
对象及其getter和setter和
Tiny
对象具有
tinyleength
变量,该变量是
整数
变量

例如,如果我正在编写一个方法,它接受一个
Big
对象参数,并在最后返回
tinyleength
,我通常会做一些事情 像这样:

public Integer getTinyLength (Big big) {
    if (big!=null && big.getSmall()!=null && big.getSmall().getTiny()!=null &&
        big.getSmall().getTiny().getTinyLength()!=null) {
    return big.getSmall().getTiny().getTinyLength();
}
else {
    // throw exception or return null or do whatever
}
因此,我的问题是,与其做这些蠢事,不如我做一些类似的事情:

try {
    return big.getSmall().getTiny().getTinyLength();
}    
catch (Exception e){
    //null pointer exception being a subclass of Exception class   
    log your error here 
    throw new NullPointerException();
}
我觉得第二段代码非常简洁,切中要害。这样做有什么缺点吗?
特别是当存在多个嵌套对象时,取消对每个嵌套对象的引用通常会导致代码高度不可读/如果错过其中一个对象,则容易出错,并导致null。

第一个代码示例效率低下,线程不安全
getSmall()
被调用四次,
getTiny()
被调用三次,
getTinyLength()
被调用两次

第二个代码示例很危险。当您只想捕获
NullPointerException
时,捕获
异常
可能会导致捕获您无意捕获的异常。此外,构建
NullPointerException
对象、抛出它、捕获它、丢弃它,以及创建另一个
NullPointerObject
的开销非常大

最好是:

Integer length = null;
if (big != null) {
    Small small = big.getSmall();
    if (small != null) {
        Tiny tiny = small.getTiny();
        if (tiny != null) {
            length = tiny.getTinyLength();
        }
    }
}
if (length != null) {
    return length;
} else {
    // Throw exception, return null, or do whatever
}
更好的做法是将代码隐藏在
Big#getTinyLength()
中的getter中

应该认真研究一下您的数据模型。你能要一个大的而不是小的吗?你能要一个不含
Tiny
Small
吗?为什么
Tiny
没有长度?如果这些成员不应该为
null
,那么让JVM检查它并抛出异常,但不要捕获它,只是重新抛出一个等价的异常:

return big.getSmall().getTiny().getTinyLength();

编辑

如果您使用的是Java 8,那么该类型可以简化您的代码:

public Integer getTinyLength (Big big) {
    return Optional.ofNullable(big)
        .map(Big::getSmall)
        .map(Small:getTiny)
        .map(Tiny::getTinyLength)
        .orElse(null);
}

这将从
big
构造一个
可选的
,并继续展开它以获得微小的长度值。如果
big
null
,或者调用中使用的任何映射函数返回
null
,则生成一个空的可选值。最后,如果存在
可选值
,则返回该值,否则返回
null

您可能会发现这很有帮助,Groovy和Kotlin中对此进行了优雅的处理。我不会费心在纯Java中处理这么长的空检查。好吧,你当然可以这么做。它将使代码更具可读性。根据问题,使用try-catch-blog并没有那个么昂贵。那个些对象中有多少可能是空的?如果它根本不可能(甚至是例外),那么这就是例外的目的。然而,我认为如果这些对象经常是空的(根据设计),那么捕获异常的成本将比完全避免异常的成本更高。如果你的应用程序不是性能关键型的,我不会担心。不过我会尝试捕捉特定的异常。不要把所有的事情都归为异常,这不是一个好的做法,最终会伤害到你。