【问题标题】:Narrowing type conversion in java [duplicate]java中的缩小类型转换[重复]
【发布时间】:2017-07-28 10:59:44
【问题描述】:

我正在学习 Java,并且对编程完全陌生。我试图了解这段代码幕后发生的事情:

short c = 234;
byte d = (byte) c;
System.out.println(d);

输出为 -22。谁能解释一下幕后发生了什么神奇的事情?

【问题讨论】:

  • 首先,您必须了解整数的二进制表示,然后,当您将值 234 截断为一个字节时,您有两种具有不同范围(和位数)的原始类型, 234 变成了负数,因为二进制表示。
  • 和 typeshort 是 16 位,byte 是 8 位。
  • 字节已签名。 234=256-22。扔掉 256,因为它都不适合一个字节,而你有 -22。

标签: java type-conversion


【解决方案1】:

二进制数23411101010‬

虽然这个数字适合 8 位,但 java 中的一个字节是有符号的,所以 java 中最大可能的字节值是 127。当设置最高有效(最左边)位时,这意味着“负数”,所以你得到的数字是负数。

现在,您可能想知道为什么当1101010 不是22 时,您得到的数字是-22。可以通过研究数字的二进制补码表示来找到这个问题的答案。

这是它的维基百科文章:https://en.wikipedia.org/wiki/Two's_complement

【讨论】:

    【解决方案2】:

    缩小转换会尝试将具有较大表示类型的值适合较窄表示类型。
    如果较大表示类型的值没有溢出较窄表示类型,没问题,值不会改变。

    例如,对于最大值为 127 的字节,此代码将使用 127 为字节变量赋值,因为它保持在窄类型的范围内:

    short c = 127;
    byte d = (byte) c;
    System.out.println(d);
    

    否则你有一个溢出。这是您的实际情况。

    例如,试试这个字节类型溢出 1 的代码:

    short c = 128;
    byte d = (byte) c;
    System.out.println(d);
    

    byte 变量将被赋值为 127 之后的下一个值。
    但它不存在。因此 JVM 在 byte 范围内循环(-128127)。
    它使用byte 的最小值:-128

    使用short c = 129;,它会产生-127,等等...

    【讨论】:

      【解决方案3】:

      谁能解释一下幕后发生了什么神奇的事情?

      根本没有魔法......检查primitives在java中的限制是什么

      byte:byte 数据类型是一个 8 位有符号二进制补码整数。 它的最小值为-128,最大值为127(含)。 byte 数据类型可用于在大型数组中节省内存, 内存节省实际上很重要。它们也可以用于 int 的位置,它们的限制有助于澄清您的代码;事实 变量的范围是有限的可以作为一种形式 文档。

      所以

      short c = 234;
      

      不适合一个字节,这就是为什么你需要cast,负的结果值是你在转换操作后得到的

      【讨论】:

      • 我明白这一点。但我的问题实际上是关于缩小转换中的信息丢失。在这种情况下,铸造的算法是什么?为什么我们得到 -22 作为输出,为什么不是 -30 或其他值?一开始我认为我们应该得到 127,因为它是字节类型可以容纳的最接近 234 的值。
      • @AmacOS 因为它会丢弃高位并将剩下的内容解释为 8 位有符号值。
      【解决方案4】:

      扩展来自@Mike Nakis 的答案。 bytes 的值是 -128 - 127。通过明确告诉编译器使用 (byte) 进行强制转换,您可以告诉编译器不关心范围约束并无论如何都适合它。

      如果你没有使用强制转换,编译器会通过打印警告你

      incompatible types: possible lossy conversion from short to byte

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-22
        • 2019-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多