避免空检查?

我想知道是否可以'避免'在Java中的空检查,从这个代码的例子:

@Override
public List<AccountBean> search(AccountConstraint... c) {
    if (c.length == 0) {
        throw new IllegalArgumentException("dao.AccountDAO.search: c.length == 0");
    }
    try {
        List<AccountBean> beans = new ArrayList<>();
        for (AccountConstraint ac : c) {
            Builder builder = new QueryBuilder.Builder("SELECT * FROM accounts");
            if (ac.getAccountId() != null) {
                builder.clause("accountId >= " + ac.getAccountId().getMin() + " AND accountId <= " + ac.getAccountId().getMax());
            }
            if (ac.getUsername() != null) {
                builder.clause("username = "" + ac.getUsername() + """);
            }
            if (ac.getPassword() != null) {
                builder.clause("password = "" + ac.getPassword() + """);
            }
            if (ac.getEmail() != null) {
                builder.clause("email = "" + ac.getEmail() + """);
            }
            PreparedStatement ps = connection.prepareStatement(builder.build().getQuery());
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                beans.add(new AccountBean(rs));
            }
        }
        return beans;
    } catch (SQLException ex) {
        throw new RuntimeException(ex);
    }
}

它必须检查4次!= null ,否则代码将失败。

是否有可能将if (object != null)语句转换为在没有NullPointerException 时才执行的单行? 当有异常时,该行应该被忽略。

我不是在谈论这里的一般语言功能,我是在谈论一个只有在你明确决定这样做时才会被启用的功能。

例如: NullCheck(builder.clause("username = "" + ac.getUsername() + """)); 将是建议代码的一部分。

在Java中有这种可能吗?

另外如果这是不可能的,在Java 8中可能直接在方法中使用方法(void)吗?

那么这样的代码实际上可以工作?

public static NullCheck(Void void) {
    try {
        void.execute();
    }
    catch (NullPointerException e) {
        //ignore
    }
}

我知道我可以将方法放在它自己的类中,该类扩展了一个接口,该接口具有方法execute() ,然后传递该类,但是这会破坏删除空检查或任何更复杂的目的。

问候。

警告:我在这里使用PreparedStatement的方式很容易出现SQL注入。 不要重复使用此代码。


是和不。

有两种方法来解决空问题:

特殊运营商,如Groovy的安全导航运营商。 如果xy抛出一个NullPointerException x?.y返回null 。 由于Java不允许创建新的运算符,因此不能在Java中执行此操作。 像JDK8这样的操作符在这里被放弃了。 如果你想要这样的东西,可以切换到Groovy或其他具有此功能的其他语言之一。

特殊类许多语言都有一个特殊的界面来表示可能为null 。 在斯卡拉它被称为选项。 Option有两个实现: None + Some 。 没有替换null 。 无论何时您想使用该值执行某些操作,都不会直接使用它,而是可以使用函数作为参数在Option上调用map 。 如果它实际上是一个无,没有任何反应,你只能回到无。 如果它是一个Some,该函数在该值上执行,并得到一个带有结果的Option。 这样你可以随时使用选项,而不用担心null

实际上它现在是特别的,所以你可以用Java自己创建一个类。 问题只在于,Java没有函数,所以你必须使用匿名类。 这使得整个事情非常繁琐,只有理论上的选择。

JDK8有一个Option类。 据我所知,它缺少map方法,这使我认为整个事情是一个坏玩笑。 但是由于最重要的工具(匿名函数)会有一个适当的Option实现,由一个常见的嫌疑犯(Google,Apache ......)提供


您可以通过假设这些方法不返回空值来避免这些检查。

你怎么能假设这一点? 通过说明AccountConstraint的规范。 然后, AccountConstraint的代码负责确保值不为null,而不是负责处理空值的search方法。 您可能必须更改AccountConstraint的设计才能执行此操作。

如果你的假设是错误的会发生什么? 也就是说,如果AccountConstraint是越野车。 将会抛出一个异常,这并不是你期待的。 但是,当你有一个bug时会发生这种情况:抛出一个意外的异常。 调试代码很容易,因为stacktrace会告诉你AccountConstraint哪个方法正在返回一个无效的空值。


就目前而言,你可能会写一个类似的方法

public void clauseIfNotNull(Builder builder, String format, Object o) {
  if (o != null) {
    builder.clause(String.format(format, o));
  }
}

然后看起来像clauseIfNotNull(builder, "username = "%s"", ac.getUsername());

除此之外,用Java 7做的事情不多。

链接地址: http://www.djcxy.com/p/76151.html

上一篇: Avoid null checks?

下一篇: Null check chain vs catching NullPointerException