Java文字值赋值行为

在Kathy Sierra的SCJP指南中,在作业章节中,我们知道我们可以声明类似这个byte b = 7; 。 在场景后面,代码是byte b = (byte) 7; 。 这是因为在java中,数字7被认为是文字int值,因此必须转换为int。

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

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

您可以阅读JLS 5.2分配转换

常量的编译时缩小意味着代码如下:

  byte theAnswer = 42; 

被允许。 如果没有缩小,整数文字42的类型为int的事实意味着需要转换为字节:

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

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

如果变量的类型是float或double,则将值集转换(第5.1.13节)应用于值v

JLS#3.10.2.Floating-Point Literals

如果浮点文字后缀为ASCII字母F或f,则浮点文字的类型为float; 否则其类型为double,并且可以选择以ASCII字母D或d为后缀

5.1.2。 扩大原始转换

从double到float的缩小基元转换由IEEE 754舍入规则(第4.2.4节)控制。 这种转换可能会失去精度,但也会失去范围,导致从非零双精度浮点零和从有限双精度浮点无穷大。 双NaN转换为浮点NaN,双无穷大转换为相同符号的浮点无穷大。

我希望上面澄清你的疑问。

要添加到先前的答案,10.543的实际表示是:

  • float :10.54300022125244140625
  • double :10.5429999999999992610355548095

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

区别:

  • 当你从int转换到byte时,你只是截断字节
  • 当你从double转换为float时,你正在做一个复杂而不是简单的操作,这是不可隐含的

为float指定double会导致精度损失,因此java会告诉您需要明确说明如何执行赋值。 简单截断可能会导致严重的舍入错误。

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

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

“在场景后面,代码是字节b =(字节)7”。

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

什么都没有关于类型转换。