byte b1 = 10 + 20; // 10 + 20 值为 int 类型,却能赋值给 byte
byte b = 10;
final byte constant = 10;
byte b1 = b + 20;  // 存在变量,编译报错
byte b2 = constant + 20; // 编译通过
int b = 10;
final int constant = 10;
byte b1 = b + 20;  // 存在变量,编译报错
byte b2 = constant + 20; // 编译通过

某些场景下,取值范围大的数据类型(int)可以直接赋值给取值范围小的(byte、shor、char)。

常量优化机制:

先判断值是否是常量, 然后再看值是否在该数据类型的取值范围内

final int constant = 126;
byte b = constant + 2; // 编译出错,128超出byte的取值范围

只有byte, short, char 可以使用常量优化机制, 转换成int类型

拓展:

short s = 10;
s = s + 20; // 编译报错,运算中存在变量
s += 20; // 等效于: s = (short) (s + 20); 没有走常量优化机制,而是进行了类型转换

这个机制简单来说,就是在定义变量时,如果右边的全部都是常量,会在编译的时候(javac的时候)直接先把右边的常量先计算了,再判断符不符合左边的数据类型范围,如果符合就编译通过,如果不符合再报错,如果右边有变量,就不会启用这个常量优化机制