byte的+=和直接相加的区别

本文详细解析了Java中Byte类型的取值范围、溢出行为及自动类型提升机制,通过具体代码示例说明了为何Byte类型的最大值127加1会变成-128,并解释了包装类Byte的缓存机制。

查看下面的代码:

public class ByteTest {
    public static void main(String[] args) {
        byte a = 1;
        byte b = 2;
        a = 1+b;
//        a+=b;
    }
}

 

发现抱错,编译器提示你提供了一个int类型的数据,但是你需要的是一个byte类型的。

原因是:byte和short类型的数据,在进行计算的时候,会自动提升数据类型为int,所以等号右边的结果类型是int,需要强转为byte类型。

在来看看第7行代码的结果:

编译器正常且结果也正确,是因为“+=”,“++”等等操作符并没有自动类型提升

再来看看下面代码的计算结果:

计算结果出乎我们的意料,为什么byte的127加1变成了-128呢?

我们知道,基本数据类型的取值范围如下:

类型字节长度  取值范围
int 4字节 -2 147 483 648 ~ 2 147 483 647
short2字节  -32 768 ~ 32 767
long 8字节 -9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807
byte 1字节  -128 ~ 127
float4字节大约±3.402 823 47E+38F(6~7位有效数字)
double 8字节 大约±1.797 693 134 862 315 70E+308(15位有效数字) 

byte的最大值是127,下面是Byte包装类的部分源码:

public final class Byte extends Number implements Comparable<Byte> {

  
    public static final byte   MIN_VALUE = -128;

    public static final byte   MAX_VALUE = 127;

   
    @SuppressWarnings("unchecked")
    public static final Class<Byte>     TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");

    public static String toString(byte b) {
        return Integer.toString((int)b, 10);
    }

    private static class ByteCache {
        private ByteCache(){}

        static final Byte cache[] = new Byte[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Byte((byte)(i - 128));
        }
    }
    public static Byte valueOf(byte b) {
        final int offset = 128;
        return ByteCache.cache[(int)b + offset];
    }
......

此包装类里面在内里面维护了一个私有的静态内部类,缓存了-128到127直接的byte对应的包装类型,通过value of这个静态方法将结果返回,此时我们取得时候同一个byte值对应的包装对象就全部是一样的。

看下面的代码就知道缓存的作用了:

public class Test {
    public static void main(String[] args)  {
        Integer i1 = 100;
        Integer i2 = 100;
        Integer i3 = 200;
        Integer i4 = 200;
        System.out.println(i1 == i2); //true
        System.out.println(i3 == i4); //false
    }
}

int里面也缓存了从-128到127之间的值,不创建对象,之间使用赋值的方式,100会之间使用缓存里面的值,所以"=="比较的地址值相同,而200超过了缓存范围,会之间使用创建对象的方式进行输出,地址值不相等,所以是false.

下面解释为什么结果是-128:

大家知道,byte类型对应1个字节,也就是8个位,最左边的是符号位,在二进制里面127是01111111,如果还想给127加一的话,结果0111 111变为1000 0000。计算机中存储负数,存的是补码的形式。左边第一位 为符号位。

 java中负数的补码转换成十进制如下:

一个数如果为正,则它的原码、反码、补码相同;一个正数的补码,将其转化为十进制,可以直接转换。

已知一个负数的补码,将其转换为十进制数,步骤:

      1、先对各位取反;

      2、将其转换为十进制数;

      3、加上负号,再减去1。
按照上面的步骤:1000 0000的结果为,第一步:0111 1111,第二步:127,第三步:-127-1 = -128,也就是最终的结果了。

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值