我有一个函数,如果参数存在于数据库中,则返回一个 ID 号。如果不是,则返回 null。这是在乞求空指针异常吗?不允许使用负 ID 号,但我认为让不存在的参数返回 null 而不是像 -1 这样的错误代码会更清楚。你怎么认为?

private Integer tidOfTerm(String name) throws SQLException {
    String sql = "SELECT tid FROM term_data WHERE name = ?";
    PreparedStatement prep = conn.prepareStatement(sql);
    prep.setString(1, name);
    ResultSet result = prep.getResultSet();

    if (result.next()) {
        return result.getInt("tid");
    }

    return null; // TODO: is this begging for a null pointer exception?
}
有帮助吗?

解决方案

这是完全合法的。如果你想避免NPE,引发自定义异常。但不要返回一个负数。如果主叫方不检查返回值,你将永远有一个问题。但这样做的计算(因为结果是例如乘以-1)绝对更难是调试比uncatched例外。

其他提示

在不给结果的查找的情况下返回一个null是代表非脑干的通常的方法。我会选择它在这种情况下。 (Lookup方法的标准Java地图类是用于在壳体使用null的地图不包含密钥的例子。)

至于为ID返回一个特殊的价值,我只打算做的,如果你的系统中已经包含了repesenting特殊的ID。

特殊值

另一种经常听到可能性在这种情况下抛出异常。这不是明智然而,使用异常传递的状态,所以我不会做,要么。

我认为这是合法的在这种情况下返回null。只要确保其意图是正确记录。

在这种情况下返回一个负值将是确定的,但它不是一个全能溶液。如果什么负的值已在分贝允许?

修改:我想补充有关SO关于返回空值或空列表(或阵列)的相关讨论的一个词。我赞成返回空列表或数组,而不是空的,但上下文的是不同的。当试图获得一个列表,它通常是一个父对象的一部分,它实际上是有意义的父对象有一个空的列表,而不是一个空引用。在这种情况下,空具有含义(=未找到)和没有任何理由避免其返回。

我希望这不是你一个真实的方法。你不关闭声明或结果集在方法范围内。

  • 不要使用错误代码!哪个值是错误的?它永远不会成为合法的返回值吗?什么也没赢。

  • 空是不好的。大多数调用者代码必须对结果进行 if not null 检查。有时 select 可能会返回 null。它的处理方式应该与没有行不同吗?

  • 抛出 NoSuchElementException 等异常,而不是返回 null。这是一个未经检查的异常,调用者可以处理它或传递它。而如果调用者想要处理的话,try catch并不比if not null更复杂。

我建议你考虑的选择模式。

选项图案用作周围的返回类型的包装,并定义了两个特殊情况:option.none()和option.some()。这样一来,你总是知道你的返回类型(可选),可检查是否有使用方法,如option.isSome()和option.isNone()在返回Option对象的值。

这样,你能保证你没有任何选中空。

当然,这一切是以增加代码复杂度为代价。

有关的选项类型的详细信息,请参阅这里( Scala代码,但相同的原理)

没有,它不会。如果你做它的操作之后,就好像它是没有nullchecking它原始的它只会抛出NPE。例如。 i++等。你举的例子是有效的(期望的JDBC代码本身泄漏资源)。如果你不需要实际id,那么你就可以在另一方面也只返回一个boolean

这可能会导致初级用户使用大麻烦。好的程序员将认识到,如果名称是可能会返回无效,那么null。如此说来更标准的办法就是加入一些exception

可能在自动装箱的组合棘手。 如果我这样做:

final int tid = tidForTerm("term");

和“术语”不存在,我会得到一个NPE,因为Java试图拆箱一个Integer(空)为原始中间体

不过,也有它实际上是很好用空的整数的情况。在具有可选int值中的实体,例如人口城市的。在这种情况下空将意味着,没有可用的信息。

一个有趣的问题和大量可能的解决方案:

  1. 创建一个 HasArgument 方法并要求用户调用它,问题是这可能很慢并且重复工作
  2. 如果值不在数据库中,则抛出异常,仅在意外情况下才应使用
  3. 使用附加值来指示无效返回,空值和负值对您有用,但如果不检查它们可能会在代码中导致问题。
  4. 返回一个带有 isValid() 和 getValue() 方法的包装器,其中 getValue() 在无效时抛出异常。这可以解决1和3的问题,但可能有点太多了。

我会说,最好的解决方案取决于你的方法命名,你应该考虑你的方法被命名什么尽可能他们是否应该返回null或抛出异常。

tidOfTerm意味着对我来说,短线有望存在,所以在发现一个不存在应抛出异常。

如果术语名称是您自己的代码的控制之下,并没有找到它表明在你的代码或环境中的错误,那么你可能要抛出IllegalArgumentException。

如果术语名称的说法是不是你的控制之下,并没有找到一个有效期为一个完全有效的情况下,那么我你的方法重命名为类似findTidForTermName给人一种轻微的暗示,某种搜索将是执行,并且因此存在搜索可能找不到任何的可能性。

我同意海报。 Integer是一个包装,因此应该用于计算,转换等(我想你打算这样做)。不要返回空值,使用负数...这是一个有点更优雅,并允许你进行更多的控制。 IMHO。

请不要写代码,返回null。这意味着,每一个调用你的代码的必须的检查空以健壮。每次。总是

考虑返回一个列表,而不是含返回值的数量,这可能是零。

是应当引起NPE和Yes你应该捕捉的是,在呼叫方法(或一些其它合适的地方)。最可能的原因,为什么你的方法将返回NULL是当没有记录和处理的正确方法是通过抛出异常。而完美的例外,告诉别人,你没有什么,他问是NPE。

返回一个错误码(例如,-1)是没有好处,因为:

a)如果有,你想了许多错误处理(如无法读取数据库,可以读取数据库,但对象不DB存在,找到对象,但一些被损坏,等等),然后返回一个错误代码不区分该类型的错误。

B)今后如果-1变成一个法律术语ID,那么这将是很难去改变它(如果你必须使用-1,则(编辑:在C)至少要做到的#define ERRORCODE -1和使用ERRORCODE到处)

scroll top