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

为什么在Java中需要无符号类型?,java,language-design,Java,Language Design,我经常听到人们抱怨Java没有无符号数据类型。参见注释示例。我想知道这是个什么问题?我用Java编程已经差不多10年了,从来没有遇到过问题。偶尔需要将字节转换为int时,需要使用和0xFF,但我不认为这是一个问题。 由于无符号数和有符号数用相同的位值表示,我能想到的唯一有符号性的地方是: 将数字转换为其他位表示时。在8、16和32位整数类型之间,如果需要,可以使用位掩码 将数字转换为十进制格式时,通常转换为字符串 通过API或协议与非Java系统进行互操作。同样,数据只是位,所以我看不出这里有

我经常听到人们抱怨Java没有无符号数据类型。参见注释示例。我想知道这是个什么问题?我用Java编程已经差不多10年了,从来没有遇到过问题。偶尔需要将字节转换为int时,需要使用<代码>和0xFF,但我不认为这是一个问题。

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

  • 将数字转换为其他位表示时。在8、16和32位整数类型之间,如果需要,可以使用位掩码
  • 将数字转换为十进制格式时,通常转换为字符串
  • 通过API或协议与非Java系统进行互操作。同样,数据只是位,所以我看不出这里有什么问题
  • 将数字用作内存或其他偏移量。对于32位整数,对于非常大的偏移量,这可能是个问题
但是,我发现,我不需要考虑无符号和有符号数之间的操作以及它们之间的转换。我错过了什么?在编程语言中使用无符号类型的实际好处是什么?使用无符号类型如何使Java变得更好

当需要转换字节到int时,有时会需要A/0xFF,但我不认为这是一个问题。

为什么不呢?“使用0xFF应用按位AND”实际上是您的代码试图表示的内容的一部分吗?如果不是,为什么它必须是你写的一部分?事实上,我发现除了将字节从一个地方复制到另一个地方之外,我想用字节做的任何事情最终都需要一个掩码。我希望我的代码是免费的;缺少无符号字节会妨碍这一点:(

另外,考虑一个API,它总是返回一个非负值,或者只接受非负值。使用一个无符号的类型可以让你清楚地表达,而不需要任何验证。我个人认为,在.NET中没有使用更多的未签名类型是很可耻的,例如对于“代码>字符串。长度< /COD>,<代码> ICOLEC。tion.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;
//这应该被认为是无符号的-因此-1的值是“真的”65535
短长度=/*某些值*/;
//这是真的签署
short foo=/*一些值*/;
布尔结果=foo<长度;
假设
foo
是100,
length
是-1。逻辑结果是什么?
length
的值代表65535,所以逻辑上
foo
比它小。但是你可能会按照上面的代码去做,得到错误的结果

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

您可能还想阅读(谷歌缓存,我相信它已经从java.sun.com上消失了),包括:

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


我使用无符号数据类型的次数是在读取与图像相对应的大数据块时,或者在使用openGL时。我个人更喜欢使用无符号数据类型,如果我知道某些内容永远不会是负面的,这是一种“安全特性”


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

如果您愿意,是的,所有的东西都是1和0。但是,您的硬件算术和逻辑单元不是这样工作的。如果您想将位存储在有符号整数值中,但执行si不自然的操作如果使用gned整数,通常会浪费存储空间和处理时间

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

如果有帮助,Guava支持将值视为无符号。@LouisWasserman:当然可以