需要帮助理解为什么这段代码不能编译

Need help on understanding why this code doesn't compile

What is the data type of x + y?

double x = 39.21;

float y = 2.1;

Explanation:

This is actually a trick question, as this code will not compile! As you may remember from Chapter 1, floating-point literals are assumed to be double, unless postfixed with an f, as in 2.1f. If the value was set properly to 2.1f, then the promotion would be similar to the last example, with both operands being promoted to a double, and the result would be a double value.

But I don't understand. If float y = 2.1; was assumed to be double there would be no need for the promotion of variable y to the double. And I'm more confused by the next problem, which is:

What is the data type of x * y / z?

short x = 14; float y = 13; double z = 30;

书上说这甚至可以编译 float y = 13;不是浮动 y = 13f。如果它们是十进制的,我是否只在浮点数旁边添加 f?我真的看不出这个问题和上述问题之间的区别。

对于第一个问题,您不能将浮点数(具有双精度值)初始化为双精度值。使用 2.1f 将该值初始化为浮点数。所以你需要 y = 2.1f。您可以阅读更多相关信息 here

对于第二个问题,之所以可行,是因为 float 是一个整数 (13),可以提升为 float 类型。

如本post所述,如果您不在数字后指定字符'f',则该值将被视为双精度值。

话虽如此,下面的代码片段将编译,但前提是将字符 'f' 添加到浮点值的末尾。

double x = 7.0;
float y = 2.0f;
System.out.print(x + y);

忽略 char、Java 将 提升 数字类型,如下所示:

byte > short > int > long > float > double

这些称为扩大转化。有关详细信息,请参阅 JLS §5.1.2. Widening Primitive Conversion

二元运算符将提升为 intlongfloatdouble,取最接近运算符两个值的那个,即结果永远不会是 byteshort。示例:byte + short 会将双方提升为 int。有关详细信息,请参阅 JLS §5.6.2. Binary Numeric Promotion

赋值运算符还将对值进行加宽转换,额外的规则是常量表达式 [=20] =]、shortint 将通过 narrowing conversion if the type of the variable is byte or short, and the value of the constant expression is representable in the type. Note, there is no rule for narrowing double constant to float. See JLS §5.2. Assignment Contexts 获取详细信息。

因此,对于您的代码:

double x = 39.21; // double constant  to  double  (identity conversion)
float y = 2.1; // fails because double constant cannot promote to float

如果代码编译成功,x + y的数据类型是什么?

x + y  // double + float  promotes to  double

答案:double

下一部分:

short x = 14;  // narrowing conversion of  int constant  to  short
float y = 13;  // widening conversion of  int constant  to  float
double z = 30; // widening conversion of  int constant  to  double

现在,x * y / z的数据类型是什么?

x * y        // short * float  promotes to  float
(x * y) / z  // (float) / double  promotes to  double

答案:double