我对Java很新。遇到了一个问题,希望能够获得更多的洞察力。
以下代码无法编译:
byte a = 10;
byte b = 20;
byte c = a + b;
编译错误 - >类型不匹配:无法从int转换为字节
自编译错误以来:
所有整数文字在Java中都被视为整数。
因此,a + b会产生一个整数文字,需要在存储到字节类型变量之前将其拼写为字节,因为可能会丢失精度。我完全理解上面的概念。
令我困惑的是浮点变量的类似概念。以下代码段成功编译:
float d = 1.2;
float e = 2.3;
float f = d + e;
根据Java:
所有小数文字在Java中都被视为十进制。
因此,类似的注释(d + e)必须产生一个十进制文字,它将被视为十进制类型并存储在一个浮点型变量中。在这里我们也失去了精确度。为什么编译器不像以前那样强迫我们进行显式类型转换?为什么这不是编译错误?
答案 0 :(得分:1)
在Java中输入转换歧义
您发布的代码中没有类型转换。
以下代码无法编译:
byte a = 10;
byte b = 20;
byte c = a + b;
Compilation error -> Type mismatch: cannot convert from int to byte
自编译错误以来:
所有整数文字在Java中都被视为整数。
不,不是。这是一个编译错误,因为类型之间的所有操作都比int
更窄,产生int
值。 JLS #4.2.2 Integer Operations:
如果移位运算符以外的整数运算符至少有一个long类型的操作数,则使用64位精度执行运算,并且数值运算符的结果为long类型。如果另一个操作数不长,则首先将其扩展(第5.1.5节)以通过数字提升(第5.6节)键入long。
否则,操作使用32位精度执行,数值运算符的结果为int类型。如果任一操作数不是int,则首先将其扩展为通过数字提升键入int。
如果您声称的Java规则确实是Java规则,则所有三行都无法编译。但是Java中没有这样的规则,就像你声称的那样。你刚刚完成了。
因此,a + b会产生整数字面
不,不。它会产生一个整数值。
需要在存储到字节类型变量之前进行类型转换为字节,因为可能会丢失精度。我完全理解上述概念。
不,你根本不理解。
令我困惑的是浮点变量的类似概念。以下代码段成功编译:
float d = 1.2;
float e = 2.3;
不,不。这两行都会产生编译错误:error: incompatible types: possible lossy conversion from double to float
。
float f = d + e;
编译。
根据Java:
所有小数文字在Java中都被视为十进制。
没有这样的规则。你刚刚做了这件事。在Java中没有“十进制文字”这样的东西,或Decimal
也没有。
因此,类似的注释(d + e)必须产生十进制文字
没有。它会产生float
值。
将被视为十进制类型
Java中没有'十进制类型'。有BigDecimal
,它是类,不是类型,但它与此问题无关。
并存储在float类型变量中。在这里我们也失去了精确度。
不,我们不。 JLS #4.2.4 'Floating-Point Operations:
如果数值运算符的至少一个操作数是double类型,则使用64位浮点运算执行运算,并且数值运算符的结果是double类型的值。如果另一个操作数不是double,则首先将其扩展(第5.1.5节)以通过数字提升键入double(第5.6节)。
否则,使用32位浮点运算执行运算,并且数值运算符的结果是float类型的值。 (如果另一个操作数不是浮点数,则首先将其扩展为通过数字提升键入float。)
您写道:
为什么编译器不会像以前那样强制我们进行显式类型转换?为什么这不是编译错误?
因为这不是错误。它不是先前错误的实例,因为它不涉及比int
更窄的类型。
不要只是制定规则,然后问为什么Java不遵守它们。检查实际规则。
答案 1 :(得分:0)
在java中,您不能将浮点值声明为:
float d = 1.2;
float e = 2.3;
因为编译器将1.2
和2.3
推断为double。你必须将它们转换为浮动:
float d = (float) 1.2;
float e = (float) 2.3;
或
float d = 1.2f;
float e = 2.3f;