偶尔将字节转换为整数时需要一个 & 0xFF,但我不认为这是一个问题。
为什么不?“应用位与 0xFF”实际上是您的代码试图表示的内容的一部分吗?如果不是,为什么它必须是你写的一部分?实际上,我发现除了将字节从一个地方复制到另一个地方之外,我想对字节做的几乎所有事情最终都需要一个掩码。我希望我的代码没有杂乱无章;无符号字节的缺乏阻碍了这一点:(
此外,考虑一个始终返回非负值或只接受非负值的 API。使用无符号类型可以让您清楚地表达这一点,而无需任何验证。就我个人而言,我认为在 .NET 中没有更多地使用无符号类型是一种耻辱,例如用于诸如String.Length
等ICollection.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 平台最奇怪的是字节类型是有符号的。我从来没有听到过对此的解释。这是非常违反直觉的,会导致各种错误。