【问题标题】:Java literal value assignment behaviourJava 文字值赋值行为
【发布时间】:2012-09-14 06:53:37
【问题描述】:

在 Kathy Sierra 编写的 SCJP 指南中,在作业章节中,我们了解到我们可以声明类似 byte b = 7; 的内容。幕后代码是byte b = (byte) 7;。之所以如此,是因为在 java 中,数字 7 被认为是字面 int 值,因此必须强制转换为 int。

现在其他情况。 Double 可以包含浮点值中包含的每个字节,因为它是一个更大的数据类型。所以我们可以说float f = 10.543; 因为 10.543 是一个很小的值,应该适合浮点数。这种数字的字面值也被认为是 Double 所以编译器应该隐式地将它转换为浮点数。但事实并非如此,编译器阻止了我们。我们必须在该值之后附加一个Ff

为什么对于字面值赋值存在这两种相互冲突的行为?简而言之,如果byte b = 7 是可能的。为什么float f = 10.543 不可能?

【问题讨论】:

  • 因为 10.543 是一个 double 并且 JLS 不允许进行这种隐式转换(是的,这是 非常精确地定义的)。试试float f = 10.543f。除了“JLS 这么说”之外,真的不需要其他原因。这些决定背后的理由可以争论一整天。

标签: java


【解决方案1】:

您可以阅读JLS 5.2 Assignment Conversion

常量的编译时变窄意味着代码如:

 byte theAnswer = 42;

是允许的。如果没有缩小范围,整数文字 42 具有 int 类型这一事实意味着需要强制转换为字节:

byte theAnswer = (byte)42;  // cast is permitted but not required

如果无法通过赋值上下文中允许的转换将表达式的类型转换为变量的类型,则会发生编译时错误。

如果变量的类型是浮点型或双精度型,则将值集转换(第 5.1.13 节)应用于值 v

JLS #3.10.2.Floating-Point Literals

如果浮点字面量以 ASCII 字母 F 或 f 为后缀,则它的类型为 float;否则它的类型是双精度的,并且可以选择以 ASCII 字母 D 或 d 为后缀

5.1.2. Widening Primitive Conversion

从 double 到 float 的窄化原语转换受 IEEE 754 舍入规则 (§4.2.4) 的约束。这种转换可能会丢失精度,但也会丢失范围,从而导致非零双精度浮点数为零和有限双精度浮点数无穷大。双精度 NaN 转换为浮点 NaN,双无穷大转换为同符号浮点无穷大。

我希望以上内容能澄清您的疑问。

【讨论】:

    【解决方案2】:

    “幕后代码是byte b = (byte) 7”。

    这是不正确的。请参阅其他几个答案中提到的JLS #5.2。它说“如果变量的类型是 byte、short 或 char,并且常量表达式的值可以用变量的类型表示,则可以使用窄化原始转换。”

    没有关于类型转换的内容。

    【讨论】:

      【解决方案3】:

      补充前面的答案,10.543 的实际表示是:

      由于您实际上指定了两个不同的数字,因此需要显式声明是有意义的。

      【讨论】:

      • 对于字节和整数表示也可以这样说。
      • 并非如此:使用(byte) 42(int) 42,您可以以两种不同的二进制表示形式存储相同的数字。使用10.543f10.543,您实际上是在指定两个不同的数字
      • 该死的..这很酷。我们如何才能找到这个实际的表示?
      • 我的答案中的两行是可点击的,您可以在这里找到更多信息:stackoverflow.com/questions/7644699/…
      【解决方案4】:

      区别:

      • 当您从 int “转换”为字节时,您只是截断字节
      • 当您从 double 转换为 float 时,您正在执行一个复杂而不简单的操作,这不能是隐式的

      【讨论】:

        【解决方案5】:

        将双精度值分配给浮点数会导致精度损失,因此 java 告诉您需要明确说明您希望它如何执行分配。简单的截断可能会导致严重的舍入错误。

        考虑以 10 为基数的有限小数实际上可能是二进制(例如浮点)基数的无限小数值。因此,明确地在浮点类型之间进行转换是一个很好的经验法则,在绝大多数情况下都很有用。

        对于像字节这样的整数类型,情况略有不同:整数类型只能在大小上有所不同,但它们都具有相同的十进制精度,即为零。因此,将较大整数类型的拟合值分配给较小的整数变量是没有歧义的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-17
          • 2019-05-14
          • 1970-01-01
          • 2015-12-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多