在Kathy Sierra的SCJP指南中,在作业章节中,我们了解到我们可以声明类似byte b = 7;
的内容。在场景后面,代码为byte b = (byte) 7;
。这是因为在java中,数字7被认为是文字int值,因此必须转换为int。
现在其他情况。 Double可以包含float值中包含的每个字节,因为它是一个更大的数据类型。所以我们可以说float f = 10.543;
因为10.543是一个很小的值,应该适合浮点数。此类数字的字面值也被视为Double,因此编译器应隐式将其强制转换为float。但事实并非如此,编译器阻止了我们。我们必须在该值之后附加F
或f
。
为什么这两个冲突的行为存在于字面值赋值?简而言之,byte b = 7
是可能的。为什么float f = 10.543
不可能?
答案 0 :(得分:6)
您可以阅读JLS 5.2 Assignment Conversion
常量的编译时缩小意味着代码如:
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
浮点文字的类型为float,如果后缀为ASCII字母F或f;否则其类型为double,并且可以选择以ASCII字母D或d
为后缀
5.1.2. Widening Primitive Conversion
从double到float的缩小基元转换由IEEE 754舍入规则(第4.2.4节)控制。这种转换可能会失去精度,但也会失去范围,导致从非零双精度浮点零和从有限双精度浮点无穷大。双NaN转换为浮点NaN,双无穷大转换为相同的浮点无穷大。
我希望上面澄清你的疑问。
答案 1 :(得分:3)
要添加到先前的答案,10.543的实际表示是:
由于您实际上指定了两个不同的数字,因此需要明确声明是有意义的。
答案 2 :(得分:1)
差异:
答案 3 :(得分:1)
为float指定double会导致精度损失,因此java会告诉您需要明确说明如何执行赋值。简单截断可能会导致严重的舍入错误。
考虑基数10中的有限小数实际上可能是二进制(例如浮点)基数中的无限小数值。因此,在浮点类型之间进行显式转换是一个很好的经验法则,在绝大多数情况下都很有用。
对于像byte这样的整数类型,情况略有不同:整数类型只能在大小上有所不同,但它们都具有相同的小数精度,即零。因此,将较大整数类型的拟合值分配给较小的积分变量时没有歧义。
答案 4 :(得分:1)
“在场景后面,代码是字节b =(字节)7”。
这不正确。请参阅其他几个答案中提到的JLS #5.2。它说“如果变量的类型是byte,short或char,则可以使用缩小的原始转换,并且常量表达式的值可以在变量的类型中表示。”
没有关于类型转换的内容。