前面谈论地还是比较浅显,讲述了什么是变量,变量参与的运算,以及在运算过程中涉及的两个知识点,自动类型提升和强制类型转换。变量参与的运算中,集中在数值型和加法运算,涉及面都很窄。接下来将会铺开来讲。
一. 深入探究变量在不同过程中背后隐藏的原理
变量在程序中参与了两种过程,定义和运算。我们举一些例子,来说明背后的原理。(除了数值型的变量外,其它类型的也可以是变量,只要一直在变动的就是变量。)
在变量的定义过程中,byte b=4; 书写出来的4默认的是int类型,将其赋值给byte类型,在DOS中,应该报错为精度缺失。但是DOS并没有报错,反而运行的很正常。原理就是:在赋值的过程中,计算机会进行判断,赋的值是否在所规定的类型范围之内。在这里4是在-128~127的范围里的,只要在这里范围里,计算机会自动地进行强制类型转换,原因就在于不会造成精度损失。同样的,byte b=4; b=3+7; 结果也不会报错,原理也是一样的。浮点型在这里却行不通?
注意:相同的数值,换种说法,DOS就会报错。byte b, b1=3, b2=7; b=b1+b2; 这里运行出错的原因在于,b1和b2是变量,以目前的3和7来看,结果是不会损失精度。但变量的特点就在于数据会变,为了防止以后超出范围,在这里直接报错。→貌似这种说法有些牵强。说的更明白一些,就是右侧的b1和b2是不确定的,两者的相加的结果可能会超出byte的范围。如果在这里将b的类型定义为int,int可以容纳两个byte类型变量的所有的范围,就不会报错。(其实计算机是一步一步进行运算的,b=b1+b2,我的理解是这样的,右侧先计算,计算的结果赋值给b,右侧计算的结果在没有赋值前是一个未知类型的数值,依据JAVA的原理,默认为int,这个int类型的数值可能小于byte范围,也可能大于byte,这样在强制转换的时候,可能损失精度。相同的原理,对于下面的例子而言,三个int类型,X X1 X2,右侧的未定义时,默认为int,如果超过int范围,先进行了舍弃,这样再赋值给左侧int X时就不会有任何问题。)
换个一种类型,三个变量之间的运算,按照byte的说法来看,这里应该会报错,但是并没有。原因就在于,计算机中,任何整数运算的结果都还是整数,即使超过精度,系统也会自动截取,所以默认的类型不会报错,但是输出的结果也不一定是正确的,除非两个参与计算的int类型数值都比较小,不超精度。
两个变量进行算术运算再赋值给另一个变量的过程中,要么右侧的结果编译不通过,要么通过了也不一定准确。