先引入一个段代码
public class Main {
public static void main(String[] args) {
byte b1 = 1,b2=2,b3,b6;
final byte b4=4,b5=6;
b6 = b4+b5;
System.out.println(b1+b2);//3
System.out.println(b6);//10
b3=(b1+b2);
System.out.println(b3+b6);
}
}
上述代码语句:
b1+b2 = 3;
b6 =10;
b3=b1+b2编译出错:
报错原因:java不兼容类型,从int转换到byte可能会有损失,
b1,b2是int类型,b3是byte类型
解释:byte类型进行变量之间的计算时,是会将类型提升到int类型再进行计算的。
----------在b3=b1+b2中,b1,b2是byte型,java中进行计算时需要将他们提升为int类型,再进行计算,b1+b2计算后已经是int类型,赋值给b3,b3是byte类型,类型不匹配,若没有强转,那么编译就不会通过,因为int类型不能直接赋值给byte类型,如若需要,则需要强转。
上述代码修改如下
b3=(byte)(b1+b2);
System.out.println(b3+b6); //13
大容量转换为小容量,称为强制类型转换
如果有不熟悉类型转换的小伙伴可以先看看这个:
但b6同样被两个byte赋值了,为什么它不报错?
----------原因就在于final,被final修饰的变量是一个常量,在这里b4可以替换成3,b5可以替换成4。即:b6=4+5;不涉及类型提升,在编译时就已经变成了b6=9
总结:Java中的byte,short,char进行计算时都会提升为int类型。
根据以上通过几个例子具体说明:
例一:
byte a=1;
a=a*2;
System.out.println(a);
解释:在java中,类型为byte,short,char类型的变量在运算的时候都会被自动转换为int类型。在式byte a=1;中变量a为byte类型,但在式a=a2 中 a2为 int 类型,而 a 还是 byte类 型,所以int类型赋值给byte类型会报精度损失,发生编译错误。将a=a2;这个式子改为a=(byte)a2;即可!(此操作为强转)
例二:关于byte的溢出问题
byte b=(byte)(123+123);
System.out.println(b); //-10
为什么结果为-10呢?
解释:首先我们要知道,数据是以补码的形式在计算机中存储的
int型246改写成补码形式为:0000 0000 1111 0110 , 原码也是它
强制转换为byte型要截断为1111 0110
但在计算机存储中,首尾表示符号位,
因此这个数为负数,根据原反补原则进行转换后该数据的原码为1000 1010
所以结果为-10
知道一个数字的补码,怎样求它的原码呢?
解释:符号位不变,其它位全部取反,然后最终的结果+1
例三:
short a = 128 ;
byte b = (byte)a ;
System.out.println(b); //-128
解释:a在计算机中的补码为0000 0000 1000 0000,原码也是它
强制类型转换后为1000 0000
在计算机中它的首位是1,故它代表负数,
根据原反补规则进行转换后该数据的原码为1000 0000
所以结果为-128
这里有一个注意的点:
二进制原码或者 8 位二进制反码的表示范围都是 -127~ +127,不能表示-128;而8位二进制补码的表示范围是 -128~+127,其中 -128的 8 位二进制补码为 10000000。
例四:
byte a = (byte)(-129) ;
System.out.println(a); //127
解释:a在计算机中的补码为1000 0000 0000 0000 0000 0000 1000 0001
a在计算机中的原码为1111 1111 1111 1111 1111 1111 0111 1111
强制转换,取后面8个字节,也就是0111 1111
所以结果是127