2

我经常听到有人抱怨 Java 没有无符号数据类型。例如,请参阅评论。我想知道这是怎么回事?我用 Java 编程已经有 10 年了,从来没有遇到过问题。有时需要将字节转换为整数& 0xFF,但我不认为这是一个问题。

由于无符号数和有符号数用相同的位值表示,我能想到的唯一有符​​号的地方是:

  • 将数字转换为其他位表示时。如果需要,您可以在 8、16 和 32 位整数类型之间使用位掩码。
  • 将数字转换为十进制格式时,通常转换为字符串。
  • 通过 API 或协议与非 Java 系统进行互操作。同样,数据只是位,所以我在这里看不到问题。
  • 使用数字作为内存或其他偏移量。对于 32 位整数,这对于非常大的偏移可能是个问题。

相反,我发现不需要考虑无符号数和有符号数之间的操作以及它们之间的转换更容易。我错过了什么?在编程语言中使用无符号类型的实际好处是什么,以及如何让 Java 变得更好?

4

3 回答 3

11

偶尔将字节转换为整数时需要一个 & 0xFF,但我不认为这是一个问题。

为什么不?“应用位与 0xFF”实际上是您的代码试图表示的内容的一部分吗?如果不是,为什么它必须是你写的一部分?实际上,我发现除了将字节从一个地方复制到另一个地方之外,我想对字节做的几乎所有事情最终都需要一个掩码。我希望我的代码没有杂乱无章;无符号字节的缺乏阻碍了这一点:(

此外,考虑一个始终返回非负值或只接受非负值的 API。使用无符号类型可以让您清楚地表达这一点,而无需任何验证。就我个人而言,我认为在 .NET 中没有更多地使用无符号类型是一种耻辱,例如用于诸如String.LengthICollection.Count之类的东西。一个值自然只能是非负数是很常见的。

Java 中缺少无符号类型是致命的缺陷吗?显然不是。是不是很烦?绝对地。

您引用的评论一针见血:

Java 缺乏无符号数据类型也反对它。是的,您可以解决它,但这并不理想,您将使用不能真正正确反映基础数据的代码。

假设您正在与另一个需要一个无符号 16 位整数的系统进行互操作,并且您想要表示数字 65535。您声称“数据只是位,所以我在这里看不到问题” - 但必须通过 - 1 表示 65535个问题。数据表示与其潜在含义之间的任何阻抗不匹配都会在编写、读取和测试代码时引入额外的减速带。

相反,我发现不需要考虑无符号数和有符号数之间的操作以及它们之间的转换更容易。

唯一需要考虑这些操作的时候是当您自然地使用两种不同类型的值时——一种是有符号的,一种是无符号的。那时,您绝对希望指出这种差异。使用有符号类型来表示自然无符号值,您仍然应该考虑差异,但您应该隐藏的事实对您来说是隐藏的。考虑:

// This should be considered unsigned - so a value of -1 is "really" 65535
short length = /* some value */;
// This is really signed
short foo = /* some value */;

boolean result = foo < length;

假设foo是 100 并且length是 -1。合乎逻辑的结果是什么?的值length 代表65535,所以逻辑上foo小于它。但是您可能会使用上面的代码并得到错误的结果。

当然他们甚至不需要在这里表示不同的类型。它们都可以是自然无符号值,表示为负数在逻辑上大于正数的有符号值。同样的错误也适用,如果您在语言中有无符号类型,则不会有问题。

您可能还想阅读Joshua Bloch 的采访(Google 缓存,因为我相信它现在已经从 java.sun.com 消失了),包括:

哦,好问题……我要说的是,Java 平台最奇怪的是字节类型是有符号的。我从来没有听到过对此的解释。这是非常违反直觉的,会导致各种错误。

于 2012-04-05T06:48:58.810 回答
2

如果你喜欢,是的,一切都是 1 和 0。但是,您的硬件算术和逻辑单元不能那样工作。如果您想将您的位存储在有符号整数值中,但执行对有符号整数不自然的操作,您通常会浪费存储空间和处理时间。

无符号整数类型在同一空间中存储的非负值是相应有符号整数类型的两倍。因此,如果您想将语言中常用的具有无符号值的任何数据(例如通常与 C 一起使用的 POSIX 日期值(无符号秒数))引入 Java,那么通常您将需要使用更广泛的整数类型比 C 会使用。如果您正在处理许多这样的值,您将再次浪费存储空间和获取执行时间。

于 2012-04-05T06:58:44.403 回答
0

我使用无符号数据类型的时候是在读取与图像相对应的大块数据或使用 openGL 时。如果我知道某些东西永远不会是负面的,我个人更喜欢无符号,作为某种“安全功能”。

无符号类型对于逐位比较很有用,我很确定它们在图形中被广泛使用。

于 2012-04-05T06:52:57.653 回答