咱们先来看一段很简单的JAVA代码
这段代码非常简单,没有任何技术含量。但是,如果我们把这段代码改成下面的样子
大家可以看到,我们只是用一个变量a代替了原来赋值表达式当中的常量1,就会出现语法错误,这是为什么呢?今天我们就用一篇短文来聊聊这个话题。
我们知道,Java语言中有4种整数类型,分别是byte、short、int和long。其中,Java编译器对byte和short类型的变量在赋值的时候,做了一点点“特殊检查”。那么编译器如何“特殊检查”这两种类型的变量呢?当编译器看到为这两种类型的变量进行赋值的时候,要进行“超范围检查”,也就是说,会检查一下给变量所赋的值会不会有可能超过范围。如果编译器认为所赋的值有可能超过这个变量所能存储的最大值或最小值,那么就会报语法错误。但是很多人都会问,程序中给变量s所赋的值并没有超过范围,为什么会报错呢?
这就要说说编译器的检查机制。当编译器看到程序中并不是用一个简单的数值对变量s进行赋值,而是把一个算术表达式赋值给了s,并且算术表达式中还出现了变量。这时候编译器就会认为这次赋值操作有可能会把一个超范围的值赋值给s,所以就报错。
可能有读者会问:第1段代码当中,也是用算术表达式给变量s赋值,为什么会就没有出现语法错呢?问题就在于:第2段程序中,给变量s赋值的算术表达式里出现了变量。编译器认为,既然是“变量”,就有可能发生改变,是一种不确定因素。编译器并不去管变量当前的值到底是多少,它认为只要是变量参与了运算,变量值有可能变化,从而可能导致赋值超范围,因此报出了语法错误。
如果我们把第2段程序中的变量a前面加上一个final关键字会如何呢?请看下面的代码
当a前面加上了final关键字,a的值不能再发生变化,它变成了一个常量。编译器就会认定这次赋值是安全的,因为a的值永远都是1,赋值肯定不会超过范围。
那么,是不是给s赋值的算术表的时候中不出现变量,赋值操作就一定不会报错呢?其实并不是这样,请看下面的例子
这次赋值操作,“=”右边的算术表达式中并没有出现变量,但是仍然会报语法错误,原因就是,编译器会提前把算术表达式的值算出来,如果发现算出来的值已经超过了byte或short的数据范围,也会报错。因此第4段程序也不能通过编译。
到这里,大家可以记住两个结论:
另外还要提醒大家,对int和long类型的变量进行赋值的时候,编译器并不采用这样的特殊检查措施。请看以下代码
大家可以看到,在上面的程序中,我们给int类型变量i1赋值时,“=”右边也是一个算术表达式,并且表达式中也有变量,但不会出现语法错误。而给i2进行赋值时,“=”右边的值已经超过了int类型的范围,也不会有问题。
通过这篇短文,相信小伙伴一定能弄明白为什么给byte和short变量赋值的时候会出错的原因。