8种基本数据类型的包装类中那些拥有常量池技术?

  • 基本数据类型和对应的包装类

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

其中double 和float两种浮点型包装类不具有常量池技术。

什么是常量池技术?

基本概念

  1. 为什么要设计字符串常量池?因为字符串的创建要耗费大量的时间和空间,频繁创建字符串影响程序性能。
  2. 创建(无论是直接赋值,还是new对象)字符串时,首先会判断字符串常量池是否有该字符串,如果有会直接引用,如果没有才会实例化该字符串,并放入常量池

例如:Integer i1 = 40;Java在编译的时候会直接将代码封装成Integer i1 = Integer.valueOf(40);

从而直接使用常量池中的对象,而不是像 Integer i1 = new Integer(40);这种情况下会创建新的对象。

但是注意这些包装类默认创建的缓存数据只适用与[-128.127]这个范围,若超出任然会去创建新的对象。

  Integer i5 = 128;
        Integer i6 = 128;
        System.out.println(i5 == i6);//false  因为 超过了一个字节的范围 会new 一个Integer对象
        System.out.println(i5.equals(i6));
        System.out.println("-----------");

        Integer i7 = 127;
        Integer i8 = 127;
        System.out.println(i7 == i8);//true 没有超过一个字节的范围 因为在方法区中存在一个 字节常量池 范围-128---127
        System.out.println(i7.equals(i8));


例题:

Integer a = 128;
Integer b = 128;
Integer a2 = 127;
Integer b2 = Integer.valueOf(127);
System.out.println(" a == b:" +(a == b));
System.out.println(" a2 == b2:" + (a2 == b2));

Integer c = new Integer(128);
System.out.println(" b=c:" + (b == c));

System.out.println(" b=c.Intner:" + (b == Integer.valueOf(128)));

Integer d = 127;
Integer e = new Integer(127);
System.out.println(" d==e:" + (d == e));
System.out.println(" d = Integer.valueOf" + (d == Integer.valueOf(127)));
System.out.println(" e = Integer.valueOf" + (e == Integer.valueOf(127)));
System.out.println(" e.equals(d):" + e.equals(d));

// 执行结果
1> a == b:false
2> a2 == b2:true
3> b=c:false
4> b=c.Intner:false
5> d==e:false
6> d = Integer.valueOf true
7> e = Integer.valueOf false
8> e.equals(d):true

分析
1>使用=号赋值,导致强制拆包装,查看字节码文件,可知调用了Integer.valueOf方法。

在这里插入图片描述

调用了Integer.valueOf方法,下面是该方法方法体,可知,如果缓存里有该值,则返回缓存里对象,没有则创建一个新的对象。因为Integer缓存存放[-128,127]之间的数,所以1>为false。

在这里插入图片描述
2> a2=127自动拆装箱等于调用Integer.valueOf()方法,所以等于b2直接使用Integer.valueOf()方法 

3> c是直接new对象,存放的是新的内存地址,b=128不在缓存范围中,因此也是直接new Integer,两个对象在内存中的地址不一样,所以false。

4> 与3>情况类似

5> d=127使用自动拆装箱,会到缓存中获取,e为new对象,所以不相同

6> 因为自动拆装箱其实本质也是调用Integer.valueOf()方法,所以,为true

7> e为new对象,Integer.valueOf(127)是获取缓存中的对象,因此false

8> 在阿里java泰山版中,有这样一段话

对于包装类的两个变量的比较推荐使用equals进行(比较的是值而不是地址)

在这里插入图片描述

说明中已经说明了原因,我就不再赘述,我们一起来看一下equals方法

在这里插入图片描述

实际就是value和intValue进行比较,我们来看一下intValue()和value

在这里插入图片描述

其实就是Integer对象里维护的final常量int值,该int值在对象被加载时,存放在方法区的元空间中(jdk1.8叫法),所以,equals比较的就是这两个int值,不论是直接复制,new对象,调用Integer.valueOf方法,只要是同一个数字,就都相等,所以为true.
 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值