Java:可以设置 Integer = null 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2128409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 19:35:58  来源:igfitidea点击:

Java: Is it ok to set Integer = null?

javaintegerautoboxingerror-code

提问by Nick Heiner

I have a function that returns an id number if the argument exists in the database. If not, it returns null. Is this begging for a null pointer exception? Negative id numbers are not permitted, but I thought it would be clearer to have non-existent arguments returning null instead of an error code like -1. What do you think?

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

回答by FRotthowe

This is perfectly legal. If you want to avoid a NPE, throw a custom exception. But don't return a negative number. If the caller doesn't check the return value, you will always have a problem. But doing falsecalculation (because the result is for instance multiplied by -1) is definitely harder to debug than an uncatched exception.

这是完全合法的。如果您想避免 NPE,请抛出自定义异常。但不要返回负数。如果调用者不检查返回值,您将始终遇到问题。但是进行错误计算(因为例如结果乘以 -1)肯定比未捕获的异常更难调试。

回答by rsp

Returning a nullin the case of a lookup that does not give a result is a normal method of representing non-existance. I would choose it in this case. (Lookup methods for the standard Java Map classes are an example for use of nullin case the map does not contain a key.)

null在没有给出结果的查找的情况下返回 a是表示不存在的正常方法。在这种情况下,我会选择它。(标准 Java Map 类的查找方法是null在映射不包含键的情况下使用的示例。)

As for returning a special value for the ID, I would only propose to do that if your system already contains special values repesenting special ID's.

至于为 ID 返回一个特殊值,我只建议在您的系统已经包含表示特殊 ID 的特殊值时才这样做。

Another often heard possibility is throwing an exception in this case. It is not wise however to use exceptions to pass state, so I would not do that either.

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

回答by Yoni

I think it is legitimate to return null in this case. Just make sure that the intention is documented properly.

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

Returning a negative value in this case would be ok, but it is not an all-around solution. What if negative values were allowed in the db?

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

EDIT: I want to add a word about the related discussions on SO regarding returning nulls or empty lists (or arrays). I am in favor of returning empty lists or arrays instead of null, but the contextis different. When trying to obtain a list, it is typically part of a parent object, and it actually makes sense for the parent object to have an empty list instead of a null reference. In this case, null has a meaning (= not found) and there is no reason to avoid returning it.

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

回答by duffymo

I hope this isn't a real method for you. You aren't closing Statement or ResultSet in method scope.

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

回答by Arne Burmeister

  • Do not use an error code! Which value is the error? will it never become a legal return value? Nothing won.

  • Null is not good. Most caller code have to do a if not null check for the result. And some times the select may return null. Should it be handled different than no row?

  • Throw an exception like NoSuchElementException instead of the return null. It is an unchecked exception, the caller can handle it or pass it up. And if the caller wants to handle, the try catch is not more complex than an if not null.

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

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

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

回答by Chaos

I suggest you consider the option pattern.

我建议你考虑期权模式。

The option pattern acts as a wrapper around your returned type, and defines two special cases: option.none() and option.some(). That way, you always know your returned type (an option), and can check if you have a value in your returned Option object using methods such as option.isSome() and option.isNone().

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

This way, you can guarantee you don't have any unchecked nulls.

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

Of course, all this comes at the cost of additional code complexity.

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

For more information on the option type, see here(Scala code, but same principal)

有关选项类型的更多信息,请参见此处(Scala 代码,但原理相同)

回答by Stephen Denne

I'd say that the best solution depends on what your method is named, and you should consider what your methods are named as much as whether they should return null or throw an exception.

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

tidOfTermimplies to me that the Term is expected to exist, so discovering that one doesn't exist should throw an exception.

tidOfTerm向我暗示 Term 应该存在,所以发现一个不存在应该抛出异常。

If the term name is under the control of your own code, and not finding it indicates a bug in your code or environment, then you might want to throw an IllegalArgumentException.

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

If the term name argument is not under your control, and not finding a valid term is a perfectly valid situation, then I'd rename your method to something like findTidForTermNamegiving a slight hint that some kind of search is going to be performed, and that there is therefore the possibility that the search might not find anything.

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

回答by josefx

An interesting problem and a large number of possible solutions:

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

  1. Create an HasArgument method and require users to call it, problem this may be slow and dupplicate work
  2. Throw an exception if a value is not in the database, should only be used if this is unexpected
  3. Use additional values to indicate an invalid return, null and negative values would work for you but if not checked they could cause problems later in the code.
  4. Return a wrapper with an isValid() and a getValue() method, where getValue() throws an exception when it is invalid. This would solve the problems of 1 and 3, but may be a bit too mutch.
  1. 创建一个 HasArgument 方法并要求用户调用它,这可能是缓慢和重复工作的问题
  2. 如果值不在数据库中,则抛出异常,仅应在意外情况下使用
  3. 使用附加值来指示无效的返回值,空值和负值对您有用,但如果不检查它们可能会导致代码稍后出现问题。
  4. 返回带有 isValid() 和 getValue() 方法的包装器,其中 getValue() 在无效时抛出异常。这将解决 1 和 3 的问题,但可能有点过分。

回答by whiskeysierra

Might be tricky in combination of Autoboxing. If i am doing this:

结合自动装箱可能会很棘手。如果我这样做:

final int tid = tidForTerm("term");

And "term" does not exist, i will get a NPE, because Java tries to unbox an Integer (null) to a primitive int.

并且“术语”不存在,我会得到一个 NPE,因为 Java 试图将一个整数(空)拆箱为一个原始整数。

Nevertheless, there are cases where it's actually good to use null for Integers. In entities having optional int values, e.g. the population of a city. In that case null would mean, no information available.

尽管如此,在某些情况下,对整数使用 null 确实很好。在具有可选 int 值的实体中,例如一个城市的人口。在这种情况下,null 意味着没有可用的信息。

回答by BalusC

No, it won't. It will only throw a NPE if you do operations on it afterwards as if it is a primitive without nullchecking it. E.g. i++and so on. Your example is valid (expect from that the JDBC code itself is leaking resources). If you don't need the actual id, then you can on the other hand also just return a boolean.

不,不会。如果您之后对其进行操作,它只会抛出一个 NPE,就好像它是一个没有空检查的原语一样。例如i++等等。您的示例是有效的(预计 JDBC 代码本身正在泄漏资源)。如果您不需要实际的id,那么另一方面您也可以只返回一个boolean.