Java中byte类型的目的是什么?

14

我在Java教程中读到了这行文字:

byte(字节):byte数据类型是一个8位有符号的二进制补码整数。它的最小值为-128,最大值为127(包含在内)。在大数组中,使用byte数据类型可以节省内存,特别是当内存使用情况非常关键时。 当变量的取值范围受限时,可以使用byte代替int来使代码更加清晰简洁;一个变量的取值范围受限的事实可以作为一种文档形式。

我不太理解粗体部分的意思,请问有人能为我解释一下吗?


3
我已经回答了,但我认为撰写这篇教程的人只是在胡说八道。没有人应该自欺欺人地认为这是一种恰当的文档形式。 - Máté Gelei
1
我认为他们并不是指它可以取代实际文档。他们可能是说通过阅读byte,你会自动想到值的范围,而不像int那样范围很大只能想到数字。 - Mr. Adobo
7个回答

16

Byte的范围是从-128到127(有符号),而int的范围是从-2,147,483,648到2,147,483,647(也是有符号的)。

这意味着,由于您将使用的值始终在该范围内,通过使用byte类型,您告诉任何阅读您代码的人,此值始终最多在-128到127之间,而无需进行文档记录。

尽管如此,适当的文档记录仍然非常重要,你应该只在特定情况下用它来提高可读性,并不是文档记录的替代品。


9
如果你正在使用的变量最大值为127,您可以使用byte代替int,这样其他人不需要在阅读任何可能检查边界的if条件后,就能知道该变量只能有一个值介于-128和127之间。因此,它是一种类似自我说明的代码--正如您引用的文本中所提到的那样。个人而言,我不建议使用这种“文档”方式--仅仅因为一个变量只能持有最大值为127并不能揭示其真正目的。

6
我想使用byte来处理实际的字节。
此外,颜色的部分(红、绿和蓝)通常具有0-255的范围(虽然byte在技术上是-128到127,但数字数量相同)。
也可能会有其他用途。
我对使用byte的一般反对意见(也许这就是为什么它没有像它应该的那样经常出现的原因)是需要大量的转换。例如,每当您对byte进行算术运算时(除了X=),它会自动提升为int(即使是byte+byte),因此如果您想将其放回byte中,则必须将其转换。
一个非常基本的例子:

FileInputStream::read返回一个包装在int(或-1)中的byte。这可以转换为byte以使其更清晰。 我不支持这个例子(因为我目前不太明白下面的操作的意义),只是说类似的操作可能有意义。

它也可以一开始就返回一个byte(如果到达文件结尾可能会抛出异常)。这可能会更清晰,但采用现在的方式也是有道理的。

FileInputStream file = new FileInputStream("Somefile.txt");
int val;
while ((val = file.read()) != -1)
{
  byte b = (byte)val;
  // ...
}

如果你对于FileInputStream不是很了解,你可能不知道read返回的是什么,因此你会看到一个int,并且你可能会认为其有效范围是整个int范围(-2^31到2^31-1),或者可能是char的范围(0-65535)(对于文件操作来说这不是一个坏的假设),但是当你看到转换为byte时,你就需要再次思考。

如果返回类型是byte,那么你就可以从一开始就知道有效范围。

另一个例子:

Color的构造函数之一可以从3个int改为3个byte,因为它们的范围限制在0-255之间。


这很令人困惑,完全脱离了OP所问的上下文。 - Mr. Adobo
@JesusAdoboLuzon 这表明read返回一个包装在int中的byte - Bernhard Barker
这并不是他发布的文档的意思。为什么你不只是将val定义为byte,然后在完成时将其转换为int,这样更明显地表明你正在使用字节(或者至少只对字节部分感兴趣,转换也可以做到这一点)。 - Mr. Adobo
@JesusAdoboLuzon FileInputStream::read 返回一个 int。返回值 -1 表示文件结束 - 如果您立即将其转换为 byte,则会丢失此信息(因为 255 也是有效的返回值,当转换为 int 时变为 -1),您需要在转换为字节之前进行 -1 检查。 - Bernhard Barker
@Duckeling:你的回答有点混淆,但我理解你的观点。 - Hải Phong

6

Java中的整数存储在32位中;字节则存储在8位中。

假设你有一个包含一百万条目的数组。哎呀!那真是太大了!

int[] foo = new int[1000000];

现在,对于foo中的每个整数,您将使用 32位 4字节内存。总共需要 400万字节 4MB

请记住,在Java中,integer是介于-2,147,483,648和2,147,483,647之间的整数。如果您的数组foo只需要包含1到100之间的整数,那么您没有使用很多数字,声明fooint数组。

这时就可以使用byteBytes可以存储介于-128和127之间的整数,非常适合您的需求!但为什么选择bytes呢?因为它们使用的空间只有整数的四分之一。现在,您的数组浪费的内存更少了:

byte[] foo = new byte[1000000];

现在,每个foo中的条目占用8位1字节的内存,因此总共,foo只占用100万字节1MB的内存。
这比使用int[]要好得多 - 您刚刚节省了3MB的内存。
显然,您不会想在保存可能超过127的数字的数组中使用此方法,因此阅读您提到的粗体行的另一种方式是:由于字节的范围有限,这使开发人员知道变量严格限制在这些范围内。没有理由让开发人员假定存储为字节的数字会超过127或小于-128。使用适当的数据类型可以节省空间,并告知其他开发人员对变量施加的限制。

1
只是说一下,你的大部分回答都集中在“节省内存”上,而这并没有用粗体标出来。 - Bernhard Barker

1
这意味着知道一个值被明确声明为一个非常小的数字可能会帮助您回忆它的目的。
当您需要为代码创建文档时,请使用真实文档,但依赖数据类型并不是文档。

0

整型(int)可以覆盖从0到4294967295或2的32次方的值。这是一个巨大的范围,如果你正在评分一个满分为100分的测试,并且所有的数字都在0到100之间,那么你就浪费了额外的空间。存储整型需要更多的内存和硬盘空间,在严肃的数据驱动应用程序中,如果你没有使用整型提供的额外范围,这将导致浪费金钱。


4
更正:一个 int 变量可以包含从 -2147483648 到 2147483647 的值。参考链接。同时,你正在处理的是“节省空间”的部分,这部分内容没有被加粗。 - Bernhard Barker
1
Java没有无符号类型。 - Bernhard Barker
哦,实际上 char 是无符号的,基本上是 boolean,请参见这里 - Bernhard Barker

0

当你想要处理来自文件或网络的流形式的数据时,通常会使用字节数据类型。这背后的原因是因为网络和文件都是基于字节的概念工作。

例如:FileOutStream始终将字节数组作为输入参数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接