如果数据库中存在参数,我有一个返回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?
}
答案 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)
一个有趣的问题和大量可能的解决方案:
答案 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的代码。这意味着每次对代码的调用必须检查是否为空,以便健壮。每次。总是
考虑返回一个包含多个返回值的列表,这些值可能为零。