6

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

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

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

4

5 回答 5

6

您可以阅读JLS 5.2 赋值转换

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

 byte theAnswer = 42;

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

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

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

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

JLS #3.10.2.浮点文字

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

5.1.2. 扩大基元转换

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

我希望以上能澄清你的疑问。

于 2012-09-14T07:02:07.993 回答
3

添加到前面的答案中,10.543 的实际表示是:

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

于 2012-09-14T07:17:31.477 回答
1

区别:

  • 当您从int“转换”为字节时,您只是截断字节
  • 当你从 double 转换为 float 时,你正在做一个复杂而不简单的操作,这不能是隐式的
于 2012-09-14T06:58:14.813 回答
1

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

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

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

于 2012-09-14T07:04:26.690 回答
1

“在幕后代码是字节 b =(字节)7”。

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

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

于 2012-09-14T10:13:02.903 回答