如何在 Java 中呈现可为空的原始类型 int?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/985151/
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
How to present the nullable primitive type int in Java?
提问by yinyueyouge
I am designing an entity class which has a field named "documentYear", which might have unsigned integer values such as 1999, 2006, etc. Meanwhile, this field might also be "unknown", that is, not sure which year the document is created.
我正在设计一个实体类,它有一个名为“documentYear”的字段,它可能有无符号整数值,例如 1999、2006 等。同时,这个字段也可能是“未知”,即不确定文档是哪一年创建。
Therefore, a nullable inttype as in C# will be well suited. However, Java does not have a nullable feature as C# has.
因此,在 C# 中可以为null 的int类型将非常适合。但是,Java 没有 C# 那样的可为空特性。
I have two options but I don't like them both:
我有两个选择,但我都不喜欢它们:
- Use
java.lang.Integerinstead of the primitive typeint; - Use -1 to present the "unknown" value
- 使用
java.lang.Integer代替原始类型int; - 使用 -1 表示“未知”值
Does anyone have better options or ideas?
有没有人有更好的选择或想法?
Update: My entity class will have tens of thousands of instances; therefore the overhead of java.lang.Integer might be too heavy for overall performance of the system.
更新:我的实体类将有数万个实例;因此 java.lang.Integer 的开销对于系统的整体性能来说可能太重了。
采纳答案by hhafez
You're going to have to either ditch the primitive type or use some arbitrary int value as your "invalid year".
您将不得不放弃原始类型或使用一些任意的 int 值作为您的“无效年份”。
A negative value is actually a good choice since there is little chance of having a valid year that would cause an integer overflow and there is no valid negative year.
负值实际上是一个不错的选择,因为存在导致整数溢出的有效年份的可能性很小,并且没有有效的负年份。
回答by Eddie
Another option is to have an associated booleanflag that indicates whether or not your year value is valid. This flag being falsewould mean the year is "unknown." This means you have to check one primitive (boolean) to know if you have a value, and if you do, check another primitive (integer).
另一种选择是有一个相关联的boolean标志来指示您的年份值是否有效。这个标志false意味着年份是“未知的”。这意味着您必须检查一个原语(布尔值)以了解您是否有值,如果有,请检查另一个原语(整数)。
Sentinel values often result in fragile code, so it's worth making the effort to avoid the sentinel value unless you are very sure that it will never be a use case.
哨兵值通常会导致代码脆弱,因此值得努力避免使用哨兵值,除非您非常确定它永远不会成为用例。
回答by Matthew Vines
Using the Integer class here is probably what you want to do. The overhead associated with the object is most likely (though not necessarily) trivial to your applications overall responsiveness and performance.
在这里使用 Integer 类可能是您想要做的。与对象相关的开销很可能(尽管不一定)对您的应用程序整体响应能力和性能来说是微不足道的。
回答by Thorarin
What's wrong with java.lang.Integer? It's a reasonable solution, unless you're storing very large amounts of this value maybe.
java.lang.Integer 有什么问题?这是一个合理的解决方案,除非您可能存储非常大量的此值。
If you wanted to use primitives, a -1 value would be a good solution as well. The only other option you have is using a separate boolean flag, like someone already suggested. Choose your poison :)
如果您想使用原语,-1 值也是一个不错的解决方案。您唯一的其他选择是使用单独的布尔标志,就像有人已经建议的那样。选择你的毒药:)
PS: damn you, I was trying to get away with a little white lie on the objects vs structs. My point was that it uses more memory, similar to the boolean flag method, although syntactically the nullable type is is nicer of course. Also, I wasn't sure someone with a Java background would know what I meant with a struct.
PS:该死的你,我试图在对象和结构上撒一点善意的谎言。我的观点是它使用更多内存,类似于布尔标志方法,尽管在语法上可空类型当然更好。另外,我不确定有 Java 背景的人会知道我对struct 的意思。
回答by Kekoa
You can use a regular int, but use a value such as Integer.MAX_VALUEor Integer.MIN_VALUEwhich are defined constants as your invalid date. It is also more obvious that -1 or a low negative value that it is invalid, it will certainly not look like a 4 digit date that we are used to seeing.
您可以使用常规 int,但使用诸如Integer.MAX_VALUE或 之类的值Integer.MIN_VALUE作为您的无效日期定义的常量。也更明显的是 -1 或低负值是无效的,它肯定不会像我们习惯看到的 4 位日期。
回答by Apocalisp
Tens of thousands of instances of Integer is not a lot. Consider expending a few hundred kilobytes rather than optimise prematurely. It's a small price to pay for correctness.
数以万计的 Integer 实例并不是很多。考虑花费几百 KB 而不是过早优化。为正确性付出的代价很小。
Beware of using sentinel values like nullor 0. This basically amounts to lying, since 0is not a year, and nullis not an integer. A common source of bugs, especially if you at some point are not the only maintainer of the software.
当心使用像null或这样的哨兵值0。这基本上相当于撒谎,因为0不是一年,null也不是整数。错误的常见来源,特别是如果您在某些时候不是软件的唯一维护者。
Consider using a type-safe null like Option, sometimes known as Maybe. Popular in languages like Scala and Haskell, this is like a container that has one or zero elements. Your field would have the type Option<Integer>, which advertises the optional nature of your year field to the type system and forces other code to deal with possibly missing years.
考虑使用类型安全的 null ,例如Option,有时称为Maybe。在 Scala 和 Haskell 等语言中很流行,这就像一个包含一个或零个元素的容器。您的字段将具有 type Option<Integer>,它将您的年份字段的可选性质广告给类型系统,并强制其他代码处理可能丢失的年份。
Here's a library that includes the Option type.
Here's how you would call your code if you were using it:
如果您正在使用它,您将如何调用您的代码:
partyLikeIts.setDocumentYear(Option.some(1999));
Option<Integer> y = doc.getDocumentYear();
if (y.isSome())
// This doc has a year
else
// This doc has no year
for (Integer year: y) {
// This code only executed if the document has a year.
}
回答by Peter Lawrey
If you have an integer and are concerned that an arbitrary value for null might be confused with a real value, you could use long instead. It is more efficient than using an Integer and Long.MIN_VALUE is no where near any valid int value.
如果您有一个整数,并且担心 null 的任意值可能会与实际值混淆,则可以改用 long。它比使用 Integer 更有效,而 Long.MIN_VALUE 远不及任何有效的 int 值。
回答by Truong Ha
java.lang.Integer is reasonable for this case. And it already implemented Serializable, so you can save just only the year field down to the HDD and load it back.
java.lang.Integer 对于这种情况是合理的。而且它已经实现了可序列化,因此您可以仅将年份字段保存到硬盘驱动器并重新加载。
回答by MB.
Another option might be to use a special value internally (-1 or Integer.MIN_VALUE or similar), but expose the integer as two methods:
另一种选择可能是在内部使用特殊值(-1 或 Integer.MIN_VALUE 或类似值),但将整数公开为两种方法:
hasValue() {
return (internalValue != -1);
}
getValue() {
if (internalValue == -1) {
throw new IllegalStateException(
"Check hasValue() before calling getValue().");
}
return internalValue;
}
回答by azz
For completeness, another option (definitely not the most efficient), is to use a wrapper class Year.
为了完整性,另一个选项(绝对不是最有效的)是使用包装类Year。
class Year {
public int year;
public Year(int year) { this.year = year; }
}
Year documentYear = null;
documentYear = new Year(2013);
Or, if it is more semantic, or you want multiple types of nullable ints (Other than Years), you can imitate C# Nullable primitives like so:
或者,如果它更具语义,或者您想要多种类型的可空整数(除年份之外),您可以像这样模仿 C# Nullable 原语:
class Int {
public int value;
public Int(int value) { this.value = value; }
@Override
public String toString() { return value; }
}

