为什么Java不支持无符号整数?
在我看来,这是一个奇怪的遗漏,因为它们允许人们编写不太可能在意外的大输入上产生溢出的代码。
此外,使用无符号整数可以是一种自我文档的形式,因为它们表明无符号整型所要保存的值永远不应该是负数。
最后,在某些情况下,无符号整数对于某些运算(如除法)更有效。
包含这些的缺点是什么?
为什么Java不支持无符号整数?
在我看来,这是一个奇怪的遗漏,因为它们允许人们编写不太可能在意外的大输入上产生溢出的代码。
此外,使用无符号整数可以是一种自我文档的形式,因为它们表明无符号整型所要保存的值永远不应该是负数。
最后,在某些情况下,无符号整数对于某些运算(如除法)更有效。
包含这些的缺点是什么?
当前回答
我能想到一个不幸的副作用。在java嵌入式数据库中,使用32位id字段可以拥有的id数量是2^31,而不是2^32(~ 20亿,而不是~ 40亿)。
其他回答
我听说它们将在接近最初的Java发行版时被包含。Oak是Java的前身,在一些规范文档中提到了使用值。不幸的是,这些都没有被引入Java语言。据任何人所知,可能由于时间限制,它们没有得到实施。
一旦有符号整型和无符号整型混合在表达式中,事情就开始变得混乱,你可能会丢失信息。将Java限制为有符号int型只能真正解决问题。我很高兴我不必担心整个有符号/无符号的问题,尽管我有时会错过字节中的第8位。
I once took a C++ course with someone on the C++ standards committee who implied that Java made the right decision to avoid having unsigned integers because (1) most programs that use unsigned integers can do just as well with signed integers and this is more natural in terms of how people think, and (2) using unsigned integers results in lots easy to create but difficult to debug issues such as integer arithmetic overflow and losing significant bits when converting between signed and unsigned types. If you mistakenly subtract 1 from 0 using signed integers it often more quickly causes your program to crash and makes it easier to find the bug than if it wraps around to 2^32 - 1, and compilers and static analysis tools and runtime checks have to assume you know what you're doing since you chose to use unsigned arithmetic. Also, negative numbers like -1 can often represent something useful, like a field being ignored/defaulted/unset while if you were using unsigned you'd have to reserve a special value like 2^32 - 1 or something similar.
Long ago, when memory was limited and processors did not automatically operate on 64 bits at once, every bit counted a lot more, so having signed vs unsigned bytes or shorts actually mattered a lot more often and was obviously the right design decision. Today just using a signed int is more than sufficient in almost all regular programming cases, and if your program really needs to use values bigger than 2^31 - 1, you often just want a long anyway. Once you're into the territory of using longs, it's even harder to come up with a reason why you really can't get by with 2^63 - 1 positive integers. Whenever we go to 128 bit processors it'll be even less of an issue.
我认为Java本身就很好,添加unsigned会使它变得复杂而没有太多好处。 即使使用简化的整数模型,大多数Java程序员也不知道基本的数字类型是如何行为的——只要阅读《Java Puzzlers》一书,就能了解您可能持有的误解。
至于实用的建议:
如果你的值是任意大小,不适合int,使用long。 如果它们不适合长期使用BigInteger。 只有在需要节省空间时,才对数组使用较小的类型。 如果你正好需要64/32/16/8位,使用long/int/short/byte,不要担心符号位,除法、比较、右移和强制转换除外。
另请参阅关于“将一个随机数生成器从C移植到Java”的回答。
我能想到一个不幸的副作用。在java嵌入式数据库中,使用32位id字段可以拥有的id数量是2^31,而不是2^32(~ 20亿,而不是~ 40亿)。