案例一:
short s = 1;
s = s + 1;
上述代码能否通过编译,为什么?
案例二:
short s = 1;
s += 1;
上述代码能否通过编译,为什么?
以上两个问题是非常经典的一道Java面试题,面试中出现的频率在70%以上。答案可能大家都非常清楚了,案例一可以不能通过编译,案例二可以,那么这又是为什么呢?
答案要从运算符的优先级、运算机制、默认数据类型和类型转换的机制中来寻找。
首先,我们来分析“ s = s + 1; ”。在这个表达式中,涉及到了加法(+)和赋值(=)两种运算。加法运算的优先级高于赋值运算,因此会先编译加法运算。在这个过程中,加号左侧为 short 类型的变量 s,右侧为常量值 1,1的默认数据类型为 int 类型,这种情况下,s 会自动类型提升,隐式转换为 int 类型。这个过程结束之后,会继续对赋值运算进行编译。此时,等号左侧为 short 类型变量 s,等号右侧为 int 类型变量,要把 int 类型变量的值赋给 short 类型变量,由于 int 类型的数据宽长为 32 位,short 类型的数据长度为16位,而变量的值在编译期间是无法确定的,所以编译器会认为在这个赋值过程中会发生数据信息丢失,从而编译不能通过。
我们再来看一些情况:
byte a = 3; // 编译正确
byte b = 1000; // 编译出错 Type mismatch: cannot convert from int to byte
float c = .7; // 编译出错 Type mismatch: cannot convert from double to float
在这个例子中,我们会有这样的疑问,同样是由 int 类型常量赋给 byte 类型变量