为什么在Java中需要无符号类型?

mse*_*ell 2 java language-design

我经常听到有人抱怨Java没有未签名的数据类型.请参阅评论.我想知道这是一个什么问题?我或多或少地用Java编程了10年,从来没有遇到过问题.偶尔在将字节转换为int时& 0xFF需要a,但我不认为这是一个问题.

由于无符号和带符号的数字用相同的位值表示,因此我能想到签名最重要的地方是:

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

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

Jon*_*eet 10

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

为什么不?"应用按位AND和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;
Run Code Online (Sandbox Code Playgroud)

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

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

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

哦,好问题......我要说的是Java平台最奇怪的事情是字节类型是签名的.我从来没有听过这个解释.这非常违反直觉并导致各种错误.