Java中Byte类型的运算细节

先引入一个例题:

public	 calss	 Test{
  public static void main(String[] args){
    byte b1=1,b2=2,b3,b6;
    final byte b4=4,b5=5;
    b6=b4+b5;
    b3=b1+b2;
    System.out.println(b3+b6);
  }
}

关于上述代码片段叙述正确的是:
			语句b3=b1+b2编译出错

解释:byte类型进行变量之间的计算时,是会将类型提升到int类型再进行计算的。

----------在b3=b1+b2中,b1,b2是byte型,java中进行计算时需要将他们提升为int类型,再进行计算,b1+b2计算后已经是int类型,赋值给b3,b3是byte类型,类型不匹配,若没有强转,那么编译就不会通过,因为int类型不能直接赋值给byte类型,如若需要,则需要强转。

但b6同样被两个byte赋值了,为什么它不报错?

----------原因就在于final,被final修饰的变量是一个常量,在这里b4可以替换成3,b5可以替换成4。即:b6=4+5;不涉及类型提升,在编译时就已经变成了b6=9

总结:Java中的byte,short,char进行计算时都会提升为int类型。

根据以上通过几个例子具体说明:

1.例1

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;即可!(此操作为强转)

2.例2(关于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

3.例3

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。

4.例4

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

你可能感兴趣的:(Java)