编译器的两点优化:
1、对于byte/short/char三种数据类型来说,如果右侧赋值的数值没有超过其对应的范围,那么javac编译器将会自动隐含地为其补上一个强制转换(byte)/(short)/(char)。
1) 如果没有超过左侧数据类型的范围,则编译器自动为其补上强行转换。
2) 如果赋值数据超过左侧数据类型的范围,则编译器直接报错。
public class Demo01Notice{
public static void main(String[] args) {
// 赋值时,如果不明确指明数值类型,默认常量值为int类型
// int => byte,正常来说,高精度赋值给低精度,需要强制类型转换
// 编译器将会自动补上一个(short)
// byte num1 = (short)10;
byte num1 = 10; // 编译器不报错,可以正常运行
System.out.println(num1);
// byte num2 = 128; // 数据超出左侧范围,编译器报错
}
}
2、在给变量赋值的时候,如果表达式右侧只有常量,没有任何变量,那么编译器javac会直接将常量表达式计算得到结果并赋值给该变量。
例:short num = 5 + 6; // 等号右边是两个常量进行加法运算,在编译器编译之后得到.class文件该语句直接就是:short num = 13;也就是说常量的加法运算是在编译时期就完成了的。这称为“编译器的常量优化”。
但是需要注意的是:一旦表达式中有变量参与运算,那么编译器就无法进行这种运算了,因为变量需要运行时才能确定具体的值和数据类型。
public class Demo02Notice {
public static void main(String[] args) {
short a = 5;
short b = 10;
// short result = a + b; //错误写法,左侧需要的时int类型
// short + short --> int + int --> int
// 右边采用常量进行加法运算,结果不超出short类型范围
short result = 5 + 8;
System.out.println(result);
// 错误写法
// short result = 1 + a + 2;
}
}