【问题标题】:Java Replace / Improve null checkJava替换/改进空检查
【发布时间】:2020-02-03 10:29:08
【问题描述】:

我有一个伪 Java 方法,其中所有内容都可以为空:

private String prepareMessage(Scope scope) {
    if (scope != null) {
        if (scope.getPermission != null) {
            if (scope.getInfo != null) {
                return "Successful";
            } else {
                return "Missing field Info";
            }
        } else if (scope.getInfo() != null) {
            return "Permission field not provided";
        }
    }
    return "Permission and Info fields not provided";
}

如何简化此代码以删除看起来很糟糕的空检查?谢谢!

【问题讨论】:

  • 你的java版本是多少?
  • Scope 类中烘焙它们?代码看起来像验证,所以你也可以使用 bean 验证。
  • @ernest_k 我正在使用 java 8
  • Scope 类的 getter 方法应该返回 Optional
  • 您可以反转空检查。而不是检查!= null,而是检查== null并返回相应的字符串。它会更具可读性。看到这个问题:softwareengineering.stackexchange.com/questions/18454/…

标签: java null optional


【解决方案1】:

你可以创建一个适合你的辅助方法,一个例子:

public String notNullOrElse(Object o, String notNull, String isNull) {
    return null != o ? notNull : isNull;
}

然后你可以改变:

if (scope.getInfo != null) {
    return "Successful";
} else {
    return "Missing field Info";
}

到:

return notNullOrElse(scope.getInfo(), "Successfull", "Missing field Info");

然而,不幸的是,有时那些可怕的空检查是必要的。

【讨论】:

  • 感谢您的想法!是的,我同意..只是想改进一下
【解决方案2】:

尝试重构代码。在大多数情况下,您可以通过重新排序代码流来简化 If - else。这使得代码覆盖率变得容易。

private String prepareMessage(Scope scope) {
    if (scope == null) {
        return "Permission and Info fields not provided";
    }

    if (scope.getPermission != null && scope.getInfo != null) {
        return "Successful";
    } else {
        return scope.getPermission == null ? "Permission field not provided" : "Missing field Info";
    }

}

这个文档很好地解释了 if-else 中的代码异味 -> https://dzone.com/articles/code-smells-if-statements

【讨论】:

  • 建议的重构改变了逻辑:如果范围不为空,则原始代码返回“权限和信息字段未提供”,但两个 getter 都将返回空。此版本将仅返回“未提供权限字段”。由于缺少上下文,因此无法评估此结果是否也有效。
  • "如果范围不为空,则返回原始代码“权限和信息字段未提供”"你错了请给括号a再看一遍。
  • 抱歉,不行!我建议你运行代码(你的和原来的)。如果范围为 null 或不为 null 并且 getPermission() 和 getInfo() 都将返回 null,则原始代码将返回“未提供权限和信息字段”。这在您的代码中有所不同。
【解决方案3】:

Java 1.7 引入了 java.util.Objects 类(this link 来自 Java 11 JavaDoc,但这在这里不重要)。

该类提供了Objects.isNull()Objects.nonNull() 方法,可在您的代码中按如下方式使用:

import static java.util.Objects.*;
…
private String prepareMessage(Scope scope) {
    if (nonNull (scope)) {
        if (nonNull (scope.getPermission())) {
            if (nonNull (scope.getInfo())) {
                return "Successful";
            } else {
                return "Missing field Info";
            }
        } else if (nonNull (scope.getInfo()) {
            return "Permission field not provided";
        }
    }
    return "Permission and Info fields not provided";
}

当然,这看起来是否更好看是一个品味问题。

替代逻辑可能如下所示(对于 Java 11):

import static java.util.Objects.*;
…
private String prepareMessage( Scope scope ) 
{
    var messages = { "Successful", "Missing field Info", "Permission field not provided", "Permission and Info field not provided" };
    var index = 0;
    var retValue = messages [3]; // No scope at all

    if( nonNull( scope ) ) 
    {
        if( isNull( scope.getPermission() ) ) index += 2;
        if( isNull( scope.getInfo() ) ) index += 1;
        retValue = messages [index];
    }
    return retValue;
}

我不想说这真的更好,只是不同而已。而且它省去了一次空检查……

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-16
    • 2021-05-15
    • 2015-07-10
    • 2021-02-02
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多