Java之128陷阱

一、了解128陷阱

想要了解128陷阱,首先要了解包装器类的知识。

1.包装器类

Java中的八种基本类型本身只能标志一种数值,
为了能将基本类型视为对象来处理,并能连接相关的方法
Java为每个基本类型提供了包装器类

①八种基本类型对应的包装器类:

byte—Byte short—Short int — Integer char—Character
long—Long float—Float double—Double boolean—Boolean

②创建包装器类型对象的两种方式:

  • 构造方法 new
    • Integer i = new Interger(1);
  • 调用包装器类型的valueOf方法
    • Double d = Double.valueOf(3.14);

③包装器类共同特点:

 对象一旦赋值,其值不能再改变

④装箱、拆箱:

  • Java中一些运算或程序是有限制的:
  • ++/–操作只能对基本数据类型
  • 集合中只能存放包装器类型对象
  • 装箱: 将基本类型转化为包装器类型 包装器类.valueOf(基本数据类型变量或常量);
  • Integer i = Integer.valueOf(10);//10是基本数据类型,i是包装器类型
  • 拆箱:将包装器类型转化为基本数据类型XX.XXXvalue();
  • int n = i.intValue();//i是包装器类型,n是包装器类型

2、什么是128陷阱

 128陷阱指的是两个Integer对象直接用==判定在某个范围内返回为true

两个Integer对象直接用==判定 在某个范围内(-128~127)返回为true;
                引用类型用==判定 就是判定的两个对象是不是地址一样

                如果传入value数值在-127~128范围内,那么所有在这个范围内被创建的对象实际  都指向同一个地址,即被预创建Integer对象所在的地址

两个Integer对象直接用==判定 在范围外返回为false;
                如果传入value数值不在范围内,那么每次被创建的对象都指向一个新的且不同的地址,即通过new关键字由JVM分配的新地址。

一个int和一个Integer对象用==判定返回true
                Integer是int的封装类,当int和Integer进行==比较的时候,Integer会自动拆装为int类型,所以返回true

看下面一段代码

    public static void main(String[] args) {
        int n = 128;
        int n1 = 128;
        int c = 127;
        Integer c1 = 127;
        Integer d = 128;
        Integer d1 = 128;
        System.out.println(n==n1);
        System.out.println(c==c1);
        System.out.println(d==d1);
        Integer.valueOf(13);
    }
运行结果是
true
true
false

在上面的示例中我们用Integer定义的数其实是简写形式,完整的写法:(自动装箱)

Integer d = Integer.valueOf(128);

当Ingeter与int比较时为true,因为拆箱总比装箱性能好(装箱要构建新的对象浪费空间)integer默认做了自动拆箱的处理

Integer就是int的包装类,自动装箱就是将基本数据类型转换为包装类;自动拆箱就是将包装类转换成基本数据类型 

二、分析128陷阱

我们从源码角度分析

 128陷阱出现的原因就是Integer的valueOf方法中有一个存储[-128-127]的catch数组,这个数组就相当于一个缓存,当我们定义的数在-128-127之间时,就直接返回该内存中的地址

 在自动装箱的方法中,由源码可知先判断了i是否存在于IntegerCache中的cache数组中,如若存在则直接返回数组中的值,若不存在则构建一个新的Integer对象

规定了cache数组的范围 

 所以当我们用==比较两个用Integer定义值为128的数时,会返回false,此时n1和n2是封装在两个对象中,比较应用.equals()方法

        Integer n1 = 128;
        Integer n2 = 128;
        System.out.println(n1.equals(n2));

返回true

 这就是我们所说的128陷阱

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值