Java推广?
升级规则是“当操作数是不同types的时候,自动二进制数字升级发生在较小的操作数types被转换为较大的”。 但是操作数是相同types的,
byte=byte+byte // Compile time error... found int..
那为什么呢?
byte
没有+运算符。 相反,两个操作数都被提升为int,所以你已经得到了
byte = byte + byte ... becomes (widening to find + operator) ... byte = int + int ... becomes (result of + operator) ... byte = int
…然后失败,因为没有从int
到byte
隐式转换。 你需要施放:
byte a = 1; byte b = 2; byte c = (byte) (a + b);
以下是JLS第5.6.2节中数字升级的实际规则:
当运算符将二进制数字提升应用于一对操作数时,每个操作数都必须表示一个可转换为数值types的值,应用以下规则,按照顺序使用扩展转换(第5.1.2节)根据需要转换操作数:
- 如果任何操作数是引用types,则执行拆箱转换(§5.1.8)。 然后:
- 如果其中一个操作数的types是double,另一个则转换为double。
- 否则,如果任一操作数的types为float,则另一个操作数转换为float。
- 否则,如果任一操作数的types是long,则另一个操作数转换为long。
- 否则,两个操作数都转换为inttypes。
向您提供了关于自动提升为“int”的正确答案。
还有一点需要注意 – 复合赋值运算符performance为隐式types的情况。 例:
byte b1 = 1; byte b2 = 2; b1 = b1 + b2; // compilation fails b1 += b2; // compilation successful
从这个SO问题 ,以及由于+
算术运算符的答案,两个操作数都转换为int
types。
byte b1 = 1; byte b2 = 2; byte b3 = b1 + b2; // compile time error
在上面的代码中, b1
和b2
值将在运行时被parsing,所以在parsing值之前,编译器会将其转换为int
。
但是如果我们考虑下面的代码,
final byte b1 = 1; final byte b2 = 2; int b3 = b1 + b2; // constant expression, value resolved at compile time
b1
和b2
是最终variables,值将在编译时parsing,所以编译不会失败。
我想谈谈一般的推广
Java只能计算操作数types相同的算术expression式
例如,在包含int和double值的expression式中,将int值提升为用于expression式的double值。
换句话说
double someVar = 1 / 2;// someVar = 0
但
double someVar = (double)1 / 2;// someVar = 0.5
为什么?
- 我们使用(double)转换
cast operator
创build其操作数"1"
的temporary
浮点副本(称为explicit conversion
) - 现在计算由浮点值(1的临时双份)除以整数2组成
- 根据上面的语句,Java执行一个名为
promotion
(或隐式转换)的操作,所以int values
被提升为double values
,以便in
expression式中使用=>整数2被提升为double - expression式变成
double someVar = 1.0 / 2.0; // someVar= 0.5
double someVar = 1.0 / 2.0; // someVar= 0.5
希望这是有帮助的,即使它超出了问题的核心