【问题标题】:In Java does anyone use short or byte?在Java中有人使用短或字节吗?
【发布时间】:2010-12-05 02:49:12
【问题描述】:

除了在流式传输中使用 (byte[]) 之外,我并没有真正看到 byte 和 short 使用得太多。另一方面,我看到长期使用实际值为|100|的情况。和字节会更合适。这是由于现在内存相对便宜的性质,还是只是开发人员不必担心的细节?

【问题讨论】:

    标签: java


    【解决方案1】:

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

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

    【讨论】:

    • 这就是我看不到它们的原因,我从不看电器或电子产品的源代码,干杯——想起来,这就是 Java 在风靡一时之前的初衷小程序,然后起飞。
    • 但是话说回来,对于设备来说,Java 是不是太慢而且太大了? c/c++ 不是那里的规范吗?
    • 可以说Java在嵌入式设备中的使用较少,但还是不少。 Java ME 非常小,而 ARM 处理器具有可以直接执行 JVM 字节码的模式。但是垃圾收集是不可预测的,因此大多数实时应用程序会使用较低级别的编程。
    • “内存的设备”——没有双关语。
    【解决方案2】:

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

    使用byteshort 的主要原因之一是为了清晰。程序代码不明确地声明只使用 8 位或 16 位,并且当您不小心使用更大的类型(没有适当的类型转换)时,您会收到编译错误。 (诚​​然,在编写代码时这也可能被视为令人讨厌的事情......但是类型转换的存在再次标志着读者发生截断的事实。)

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

    所以我猜开发人员没有像您(C 开发人员?)所期望的那样使用 byteshort 的主要原因是它确实没有太大(或通常任何)差异. Java 开发人员不会像老式 C 开发人员那样痴迷内存使用 :-)。

    【讨论】:

    • 如果你试图沉迷于内存使用,我认为 Java 会让你发疯。但是,作为一名 Java 开发人员,很高兴知道我正在“尽我所能”,所以我总是尽可能选择最简洁的类型。这不仅与内存使用有关,还与清晰度有关。
    • @ChrisHatton - 如果您担心内存使用和性能,那么“您的位”可能是浪费精力(或有害)。严重的是,无方向的微优化通常是白费力气。我已经提到了清晰度问题。
    • 您确实可以节省内存,尽管数量很少。在下面查看我的答案:stackoverflow.com/questions/1539793/…
    【解决方案3】:

    在 64 位处理器中,寄存器都是 64 位的,因此如果将局部变量分配给寄存器并且是布尔值、字节、短、字符、整数、浮点、双精度或长整数,则不会使用内存,不节省任何资源。 对象是 8 字节对齐的,因此它们总是占用内存中 8 字节的倍数。这意味着 Boolean、Byte、Short、Character、Integer、Long、Float 和 Double、AtomicBoolean、AtomicInteger、AtomicLong、AtomicReference 都使用相同的内存量。

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

    还值得注意的是,一个 GB 的服务器成本约为 80 英镑,因此一个 MB 约为 8 便士,一个 KB 约为 0.008 便士。 byte 和 long 之间的差异约为 0.00006 便士。你的时间比这更有价值。尤其是如果您遇到过由于数据类型太小而导致的错误。

    【讨论】:

    • 关于边界的很好提醒。计算也很有趣,但我很确定 int 或 long 不仅仅是为了避免错误。这更像是一种习惯。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      bytes 和 shorts 的算术比ints 更尴尬。例如,如果b1b2 是两个byte 变量,则不能写byte b3 = b1 + b2 来添加它们。这是因为 Java 从不在内部对小于 int 的任何事物进行算术运算,因此表达式 b1 + b2 的类型为 int,即使它只是添加两个 byte 值。你必须改写byte b3 = (byte) (b1 + b2)

      【讨论】:

      • 我只是在学习 Java,这是我最初遇到的困难。我不明白为什么我的书总是使用 int 类型。例如,在一个月的天数中使用 int 类型对我来说没有意义。所以我会在我的代码中更改它,然后会遇到问题。
      【解决方案6】:

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

      他说

      “在简单变量中使用 byte 或 short 来代替 int 并不能节省任何空间,因为大多数 Java 实现都会在字边界上对齐堆栈变量和对象成员”

      这不是真的。以下是在 Oracle JDK1.8.0 上运行的,jol

      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 个字节。 所以它确实为每个类实例节省了 8 个字节的内存。

      【讨论】:

        【解决方案7】:

        在创建基于 16 位架构的模拟器时,我广泛使用了short。我考虑过使用char,这样我就可以得到无符号的东西,但使用真正整数类型的精神最终胜出。

        编辑: 关于当我需要最重要的位时我做了什么的不可避免的问题:我正在模仿的东西碰巧几乎从未被使用过。在少数使用它的地方,我只是使用了按位修饰符或数学黑客。

        【讨论】:

          【解决方案8】:

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

          【讨论】:

            【解决方案9】:

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

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

            【讨论】:

              【解决方案10】:

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

              【讨论】:

                【解决方案11】:

                大多数时候,开发人员(Java、C#、BASIC 等)没有真正好的技术理由来决定使用 int、short 或 byte - 当然,当容量足够时。如果价值低于 20 亿,那么 int 会是。

                您确定我们会有 255 岁以上的人吗?好吧,你永远不知道!

                32,767 个可能的国家还不够吗?不要想得太小!

                在您的示例中,您可以对包含 100 的字节变量非常满意,如果您绝对确定它永远不会溢出。为什么男生用的最多的是 int?因为……因为。

                这是我们大多数人都会做的事情之一,因为我们大部分时间都是这样看的,而且从来没有提出不同的要求。

                当然,我并不反对“万物互联”。我只是更喜欢为每种值使用正确的类型,没有压力。

                【讨论】:

                  【解决方案12】:

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

                  在 Java 中编码字符串

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

                  为了对字符串进行编码,我们将它们转换为与 ASCII 兼容的 UTF-8。一种方法是使用 java core,你可以找到更多的方法去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 是一个底层使用 char 数组的 Object,包括其他数据,您可以在 this answer 中找到更多信息。

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

                  【讨论】:

                    猜你喜欢
                    • 2010-09-23
                    • 2010-10-18
                    • 1970-01-01
                    • 2023-03-27
                    • 1970-01-01
                    • 1970-01-01
                    • 2023-03-22
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多