在Java中,有人使用short或byte吗?

时间:2009-10-08 19:00:09

标签: java

除了在流媒体中使用(byte [])之外,我并没有真正看到字节和短片的使用情况。另一方面,我看到长期使用的实际值是| 100 |和byte更合适。这是现在相对便宜的内存性质的结果,还是这只是开发人员不必担心的细节?

12 个答案:

答案 0 :(得分:33)

在为内存或磁盘空间不足的嵌入式设备编程时使用它们。如电器和其他电子设备。

字节也用于低级Web编程,您可以使用标题等向Web服务器发送请求。

答案 1 :(得分:22)

在处理来自文件或网络连接的原始数据时经常使用byte数据类型,尽管它主要用作byte[]shortshort[]类型通常与GUI和图像处理(用于像素位置和图像大小)以及声音处理结合使用。

使用byteshort的主要原因之一是清晰度。程序代码无条件地声明只使用8位或16位,并且当您意外使用更大的类型(没有适当的类型转换)时,您会收到编译错误。 (不可否认,在编写代码时,这也可能被视为一种麻烦......但是,再次出现的类型转换标志着读者发生了截断这一事实。)

在简单变量中使用byteshort而不是int,不会节省任何空间,因为大多数Java实现都会在字边界上对齐堆栈变量和对象成员。但是,原始数组类型的处理方式不同;即,booleanbytecharshort数组的元素是字节对齐的。但除非数组大小或数量庞大,否则它们对应用程序的整体内存使用量没有任何重大贡献。

所以我想,开发人员不使用byteshort和你(一个C开发人员?)可能期望的主要原因是它确实没有那么多(或者通常任何)差异。 Java开发人员往往不会像老式C开发人员那样过度使用内存使用情况:-)。

答案 2 :(得分:13)

在64位处理器中,寄存器都是64位,所以如果你的局部变量被分配给一个寄存器并且是boolean,byte,short,char,int,float,double或long,它就不会使用内存,不保存任何资源。 对象是8字节对齐的,因此它们总是占用内存中8字节的倍数。这意味着布尔,字节,短,字符,整数,长,浮点和双精度,AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference都使用相同数量的内存。

如前所述,短类型用于数组和读/写数据格式。即使这样,短期也不经常使用恕我直言。

值得注意的是,GB在服务器上花费大约80英镑,因此MB大约为8便士,KB大约为0.008便士。字节和长度之间的差异大约是0.00006便士。你的时间比这更值钱。 esp如果你有一个因数据类型太小而导致的错误。

答案 3 :(得分:5)

在处理二进制格式和DataInput / DataOutput实例时,我经常会使用shortbyte类型。如果规范说明下一个值是8位或16位值并且将它们提升为int没有价值(可能它们是位标志),那么它们是显而易见的选择。

答案 4 :(得分:4)

byteshort上的算术比使用int更尴尬。例如,如果b1b2是两个byte变量,则无法编写byte b3 = b1 + b2来添加它们。这是因为Java从不在int之内的任何内部进行算术运算,因此表达式b1 + b2的类型为int,即使它只添加了两个byte值。你必须改为编写byte b3 = (byte) (b1 + b2)

答案 5 :(得分:3)

Stephen C's answer above不正确。 (对不起,我没有足够的声誉积分来发表评论,所以我必须在这里发布答案)

他说

“由于大多数Java实现在字边界上对齐堆栈变量和对象成员,因此在简单变量而不是int中使用字节或short不会节省任何空间”

这不是事实。以下代码在jol

上的Oracle JDK1.8.0上运行
public class CompareShorts {
    public static void main(String[] args) {
        System.out.println(VM.current().details());
        System.out.println(ClassLayout.parseInstance(new PersonalDetailA()).toPrintable());
        System.out.println(ClassLayout.parseInstance(new PersonalDetailB()).toPrintable());
    }
}
class PersonalDetailA {
     short height;
     byte color;
     byte gender;
}

class PersonalDetailB{
     int height;
     int color;
     int gender;
}

输出:

# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# Objects are 8 bytes aligned.
# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

com.hunterstudy.springstudy.PersonalDetailA object internals:
 OFFSET  SIZE    TYPE DESCRIPTION                               VALUE
      0     4         (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4         (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4         (object header)                           82 22 01 f8 (10000010 00100010 00000001 11111000) (-134143358)
     12     2   short PersonalDetailA.height                    0
     14     1    byte PersonalDetailA.color                     0
     15     1    byte PersonalDetailA.gender                    0
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

com.hunterstudy.springstudy.PersonalDetailB object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           e1 24 01 f8 (11100001 00100100 00000001 11111000) (-134142751)
     12     4    int PersonalDetailB.height                    0
     16     4    int PersonalDetailB.color                     0
     20     4    int PersonalDetailB.gender                    0
Instance size: 24 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

如您所见,使用shorts和bytes的类实例占用16个字节,使用ints的类实例占用24个字节。 因此,每个类实例确实节省了八个字节的内存。

答案 6 :(得分:2)

在创建基于16位架构的仿真器时,我广泛使用了short。我考虑使用char,所以我可以使用无符号的东西,但最终使用真实整数类型的精神赢了。

编辑关于我在需要最重要的一点时所做的事情的不可避免的问题:我正在模仿它的事情几乎从未被使用过。在它使用的少数几个地方,我只使用了按位修饰符或数学hackery。

答案 7 :(得分:1)

我认为在大多数应用程序中,short没有域名含义,因此使用Integer更有意义。

答案 8 :(得分:1)

short和其他人经常用于存储图像数据。请注意,它是真正重要的位数,而不是算术属性(只会导致升级到int或更好。

short也用作JavaCard中的数组索引(1.0和2.0,IIRC,但不是3.0,它也有HTTP堆栈和Web服务)。

答案 9 :(得分:1)

byte []一直在发生;缓冲区,特别适用于网络,文件,图形,序列化等。

答案 10 :(得分:0)

大多数情况下,当容量足够时,开发人员(Java,C#,BASIC等)决定使用int,short或byte时,从来没有真正好的技术理由。如果该值将低于20亿,那么它将是。

你确定我们的人会超过255岁吗?好吧,你永远不知道!

不是32,767个可能的国家吗?不要以为太小了!

在你的例子中,你可以非常满意你的字节变量包含100,如果你绝对肯定它永远不会溢出。为什么人们最常使用int?因为....因为。

这是我们大多数人刚才所做的事情之一,因为我们大部分时间都是这样做的,从来没有用不同的方式。

当然,我没有反对“所有事情”。我只是喜欢为每种价值使用正确的类型,不涉及压力。

答案 11 :(得分:0)

您遇到的一般信息是 byte,通常 byte [] 用于处理二进制数据,例如图像文件,或通过网络发送数据。我现在要提一下其他用例:

在 Java 中编码字符串

在Java中,String对象使用UTF-16,后者是immutable,即不能被修改。

为了对字符串进行编码,我们将它们转换为与 ASCII 兼容的 UTF-8。一种方法是使用java核心,你可以找到更多的方法here

为了执行编码,我们将原始字符串字节复制到字节数组,然后创建所需的字节数组。下面,我将举一个简单的例子来说明为什么我们需要对字符串进行编码,以及如何进行编码:

  • 为什么编码很重要?

假设您有这个德语单词“Tschüss”并且您使用的是 US-ASCII:

String germanString = "Tschüss";
byte[] germanBytes = germanString.getBytes();

String asciiEncodedString = new String(germanBytes,StandardCharsets.US_ASCII);

assertNotEquals(asciiEncodedString, germanString);

输出将是:

<块引用>

Tsch?ss

因为 US_ASCII 无法识别“ü”。

现在这是一个有效的例子:

String germanString = "Tschüss";
byte[] germanBytes = germanString.getBytes(StandardCharsets.UTF_8);

String utf8EncodedString = new String(germanBytes, StandardCharsets.UTF_8);

assertEquals(germanString, utf8EncodedString);

byte[ ] 有时性能优于字符串

作为记录,Java String 是一个在底层使用字符数组的对象,包括其他数据,您可以在 this answer 中找到更多信息。

现在想象一下您想要解析大量字符串数据并使用例如 split 方法的情况。在这种情况下,您将有不同的对象(不同的字符数组)分布在内存中的不同位置,这会导致 CPU 的局部性,与这种情况相反从一个位置开始,您就有一个字节数组。您可以在这篇有趣的帖子 this one 中找到更多信息。