源码中看128陷阱及一个简单例子学懂
2022/1/15 22:03:36
本文主要是介绍源码中看128陷阱及一个简单例子学懂,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
128陷阱涉及自动装箱内容,可先去(62条消息) 自动拆装箱_Edward_Mcc的博客-CSDN博客简单学习下。
128陷阱
所谓128陷阱就是,int自动装箱为Integer时,-128到127范围内的Integer对像相同的数字共用一块内存空间
// public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high)//大于-128且小于127 return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
(自动装箱的valueOf方法)
/** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. The size of the cache * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option. * During VM initialization, java.lang.Integer.IntegerCache.high property * may be set and saved in the private system properties in the * sun.misc.VM class. */ private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }
从上面两段代码可以看出,在自动装箱的情况下,缓存通过一个for循环实现。
从低到高创建整数存储在一个整数数组中。这个缓存会在Integer类第一次被使用的时候初始化出来。当通过valueOf方法创建对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象
最大值127可以通过-XX:AutoBoxCacheMax=size修改。
一个简单的例子,
Integer a1=50; int a2=50; Integer a3=Integer.valueOf(50); Integer a4=new Integer(50); Integer bb=200; Integer bbb=200; System.out.println(a1==a2); //结果为true a1是Integer对象,a2是int,这里比较的是值.Integer会自动拆箱成int,然后进行值的比较。所以为真。 System.out.println(a1==a3); //true 因为 a3 和a1 同一引用,所以,为真。(128陷阱) System.out.println(a1==a4); //false a4 是重新创建的对象,所以 a3,a4 是指向不同的对象,因此比较结果为假。(new出来的对象,不满足自动装箱的128陷阱 注意是自动) System.out.println(a2==a2); //true 同样只是比较值 System.out.println(bb==bbb); //false bb和bbb都是自动装箱,但是大于127 所以不满足128陷阱的相同应用,地址不同,所以false
这篇关于源码中看128陷阱及一个简单例子学懂的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-01后台管理开发学习:新手入门指南
- 2024-11-01后台管理系统开发学习:新手入门教程
- 2024-11-01后台开发学习:从入门到实践的简单教程
- 2024-11-01后台综合解决方案学习:从入门到初级实战教程
- 2024-11-01接口模块封装学习入门教程
- 2024-11-01请求动作封装学习:新手入门教程
- 2024-11-01登录鉴权入门:新手必读指南
- 2024-11-01动态面包屑入门:轻松掌握导航设计技巧
- 2024-11-01动态权限入门:新手必读指南
- 2024-11-01动态主题处理入门:新手必读指南