Java:设置Integer = null可以吗?

时间:2010-01-24 19:27:19

标签: java integer autoboxing error-code

如果数据库中存在参数,我有一个返回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?
}

14 个答案:

答案 0 :(得分:15)

这是完全合法的。如果要避免使用NPE,请抛出自定义异常。但是不要返回负数。如果调用者没有检查返回值,则总会出现问题。但是,进行 false 计算(因为结果例如乘以-1)肯定比未捕获的异常更难调试。

答案 1 :(得分:3)

如果查询没有给出结果,则返回null是表示不存在的常规方法。在这种情况下我会选择它。 (标准Java Map类的查找方法是使用null的示例,以防地图不包含密钥。)

至于为ID返回一个特殊值,如果您的系统已经包含特殊值,则我只建议这样做。

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

答案 2 :(得分:2)

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

在这种情况下返回负值是可以的,但它不是一个全面的解决方案。如果db中允许负值怎么办?

编辑:我想在SO上添加关于返回空值或空列表(或数组)的相关讨论。我赞成返回空列表或数组而不是null,但 context 是不同的。在尝试获取列表时,它通常是父对象的一部分,并且实际上父对象具有空列表而不是空引用是有意义的。在这种情况下,null具有含义(=未找到),并且没有理由避免返回它。

答案 3 :(得分:1)

我希望这对你来说不是一个真正的方法。您没有关闭方法范围中的Statement或ResultSet。

答案 4 :(得分:1)

  • 请勿使用错误代码!哪个值是错误的?它永远不会成为合法的回报价值吗?什么都没赢。

  • Null不好。大多数调用者代码必须对结果执行if not null检查。有时候select可能会返回null。是否应该处理不同的行?

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

答案 5 :(得分:1)

我建议你考虑选项模式。

选项模式充当返回类型的包装器,并定义了两种特殊情况:option.none()和option.some()。这样,您始终知道返回的类型(选项),并且可以使用option.isSome()和option.isNone()等方法检查返回的Option对象中是否有值。

这样,您可以保证没有任何未经检查的空值。

当然,所有这些都是以额外的代码复杂性为代价的。

有关选项类型的更多信息,请参阅here(Scala代码,但相同的主体)

答案 6 :(得分:0)

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

答案 7 :(得分:0)

这可能会给新手用户带来很大麻烦。好的程序员会认识到,如果名称无效,则可能会返回null。说过更标准的事情就是抛出一些exception

答案 8 :(得分:0)

组合Autoboxing可能会很棘手。 如果我这样做:

final int tid = tidForTerm("term");

并且“term”不存在,我将得到一个NPE,因为Java试图将整数(null)解包为原始int。

然而,有些情况下,对整数使用null实际上是好的。在具有可选int值的实体中,例如,一个城市的人口。在这种情况下,null意味着,没有可用的信息。

答案 9 :(得分:0)

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

  1. 创建一个HasArgument方法并要求用户调用它,问题可能很慢且工作量很大
  2. 如果值不在数据库中,则抛出异常,只有在出现意外时才应使用
  3. 使用其他值来表示无效的返回值,null和Negative值对您有用,但如果不进行检查,则可能会在以后的代码中导致问题。
  4. 返回一个包含isValid()和getValue()方法的包装器,其中getValue()在无效时抛出异常。这将解决1和3的问题,但可能有点过分。

答案 10 :(得分:0)

我会说最好的解决方案取决于你的方法的名称,你应该考虑你的方法的名称,以及它们是否应该返回null或抛出异常。

tidOfTerm向我暗示预期该术语存在,因此发现一个术语不存在应该抛出异常。

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

如果术语名称参数不在您的控制之下,并且找不到有效的术语是完全有效的情况,那么我会将您的方法重命名为findTidForTermName,稍微提示某种搜索将要执行,因此搜索可能找不到任何东西。

答案 11 :(得分:-3)

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

答案 12 :(得分:-3)

是的,它应该导致NPE,是的,你应该在调用方法(或其他一些合适的地方)中捕获它。你的方法返回NULL的最可能原因是没有记录时,处理它的正确方法是抛出异常。 NPE是告诉别人你没有要求的完美例外。

返回错误代码(例如-1)并不好,因为:

a)如果你想要处理很多错误(例如无法读取DB,可以读取DB但DB中不存在对象,找到对象但是有些东西已经损坏等),那么返回错误代码就无法区分错误的类型。

b)将来如果-1成为合法术语id,那么就很难改变它(如果你必须使用-1,那么(编辑:在C中)至少要做#define ERRORCODE -1并使用ERRORCODE无处不在)

答案 13 :(得分:-3)

请不要编写返回null的代码。这意味着每次对代码的调用必须检查是否为空,以便健壮。每次。总是

考虑返回一个包含多个返回值的列表,这些值可能为零。