欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > Java基本类型与包装类型

Java基本类型与包装类型

2025/1/31 14:50:20 来源:https://blog.csdn.net/weixin_45186425/article/details/145355941  浏览:    关键词:Java基本类型与包装类型

区别

基本数据类型都有对应的包装类型,都有一种机制,使得基本类型可以包装类互相转换。
基本类型和包装类型的区别:

  1. 包装类型可以为null,使得可以用于封装POJO
  2. 包装类型可以用于泛型,基本类型不能
  3. 基本类型更高效,因为占用更少的内存空间
  4. 包装类型尽量用equals比较内容,用==比较可能相等,也可能不等

装箱:基本类型变包装类,通过包装类的valueOf方法实现
拆箱:包装类变基本类型,通过包装类的xxxValue实现
自动装箱和拆箱:自动装箱和拆箱依赖于享元设计模式
注意点:频繁装箱会创建对象,造成内存消耗和GC压力,要尽量避免装箱,装箱后,不能使用==判断相等

缓存机制

包装类型大部分都用到了缓存机制来提升性能。所谓缓存机制,就是Java提前帮我们创建好了一些对象,放在缓存池中,当用到了这些对象,就直接拿来用,而不需要创建新的对象。因此,如果走了缓存池,就是同一个对象。
以int和Integer为例

int i1=100;
Integer i2=100;             // 相当于 Integer i2=Integer.valueOf(100);
System.out.println(i1==i2); // true,与基本类型运算时,i2会自动拆箱,i2走的缓存池Integer i3=new Integer(100);
System.out.println(i2==i3); // false,i3创建了一个新对象,没走缓存池,所以和i2不是同一个对象Integer i4=new Integer(100);
System.out.println(i3==i4); // false,i4同i3一样,新建的对象Integer i5=Integer.valueOf(100);
Integer i6=Integer.valueOf(100);
System.out.println(i1==i5); // true
System.out.println(i5==i6); // true,i1==i5==i6,i2,i5,i6都一样,走的缓存池
System.out.println(i3==i5); // false
System.out.println(i4==i5); // falseint i7=new Integer(100); // 自动拆箱
System.out.println(i2==i7);  // trueInteger a=200;
Integer b=200;
System.out.println(a==b);  // false,不在缓存池范围内,所以是不同的对象int c=200;
Integer d=200;
System.out.println(c==d); // true,注意包装类型与基本类型运算时,都会自动拆箱,与范围无关

缓存机制的根源就在于 XXXvalueOf 的源码

    public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);}private static class IntegerCache {static final int low = -128;static final int high;static final Integer cache[];static {// high value may be configured by propertyint h = 127;// 省略...high = h;// 省略...// range [-128, 127] must be interned (JLS7 5.1.7)assert IntegerCache.high >= 127;}}

所以只要是Integer a=100Integer b=Ingeter.valueOf(100)都是一样的,但new Integer就会 创建新对象。从源码可以看到,Integer的缓存范围是-128到127,也就是说这个范围内的装箱,就会走缓存使用同一个对象,而不在这个范围内,就会创建新对象。这就是上面代码中a和b不相等但i1==i2==i5==i6的原因。
实际上,Java的四个整型,Short,Byte, Integer, Long的缓存池范围都是-128-127。Character的范围是0-127。Boolean直接返回True或False

另外注意自动装箱和拆箱带来的隐患:

Long sum = 0L;
for (int i = 0; i < Integer.MAX_VALUE;i++) { sum += i;}

sum 由于被声明成了包装类型 Long 而不是基本类型 long,所以 sum += i 进行了大量的拆装箱操作(sum 先拆箱和 i 相加,然后再装箱赋值给 sum),所以性能很差。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com