Java包装类缓存
2021/7/14 22:05:25
本文主要是介绍Java包装类缓存,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Java基本类型的包装类的大部分都实现了常量池技术,即Byte,Short,Integer,Long
这四种包装类默认创建了数值[-128,127]的相应类型的缓存数据,Character创建了数值在[0,127]范围的缓存数据,Boolean直接返回true或者false。超出此范围会创建新的对象。
public static Boolean vatue0f(boolean b){ return(b?TRUE:FALSE); }
private static class CharacterCache{ private CharacterCache(){} static final Character cache[]=new Character[127+1]; static{ for(int i=0;i<cache.Length;i++) cache[i]=new Character((char)i); } }
浮点类型的包装类Float和Double没有实现常量池技术
缓存区间设置为[-128,127]的原因:
https://github.com/Snailclimb/JavaGuide/issues/461
由于Integer变量是对一个Integer对象的引用,所以两个通过new生成的Integer变量永远是不相等的(在堆内存地址不同)。
Integer i = new Integer(100); Integer j = new Integer(100); System.out.print(i == j); //false
非new生成的Integer变量和new Integer()生成的变量比较时,结果为false。(非new生成的 Integer变量指向的是java常量池中的对象,而new Integer()生成的变量指向堆中新建的对象,两者在内存中的地址不同)
Integer b = new Integer(100); Integer c=100; System.out.println(b == c); // false
对于两个非new生成的Integer对象,进行比较时,如果两个变量的值在区间-128到127之间,则为true,如果不在这区间,则为false
Integer i = 100; Integer j = 100; System.out.print(i == j); //true Integer i = 128; Integer j = 128; System.out.print(i == j); //false
因为当值在 -128 ~ 127之间时,java会进行自动装箱,然后会对值进行缓存,如果有相同的值,会直接在缓存中取出使用。缓存是通过Integer的内部类IntegerCache来完成的。当值超出此范围,会在堆中 new出一个对象来存储。
给一个Integer对象赋一个int值的时候,会调用Integer类的静态方法valueOf,
Integer i=30;在编译的时候会直接将30封装为Integer。
i=Integer.valueOf(30);会使用常量池中的对象。
源码:
public static Integer valueOf(String s, int radix) throws NumberFormatException { return Integer.valueOf(parseInt(s,radix)); }
/** * (1)在-128~127之内:静态常量池中cache数组是static final类型,该对象会被存储于静 态常量池中。 * cache数组里面的元素不是static final类型,而是cache[k] = new Integer(j++), * 这些元素是存储于堆中,只是cache数组对象存储的是堆中的Integer对象的地址 * * (2)在-128~127 之外:在堆中新建一个 Integer对象,并返回。 */ public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) { return IntegerCache.cache[i + (-IntegerCache.low)]; } return new Integer(i); }
IntegerCache是Integer的内部类,源码:
/** * 缓存支持自动装箱的对象标识语义 -128和127(含)。 * 缓存在第一次使用时初始化。 缓存的大小可以由-XX:AutoBoxCacheMax = <size>选项控制。 * 在VM初始化期间,java.lang.Integer.IntegerCache.high属性可以设置并保存在私有系统 属性中 */ 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) { 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); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) { cache[k] = new Integer(j++); // 创建一个对象 } } private IntegerCache() {} }
最大边界可以通过-XX:AutoBoxCacheMax进行配置
Integer a=newInteger(48); Integer b=newInteger(48); Integer c=newInteger(0); System.out.println("a=b+c"+(a==b+c));
由于+不适用于Integer对象,所以b,c会先自动拆箱进行数值相加,又由于Integer对象无法与数值直接比较,所以a自动拆箱为int,最终转为48==48
这篇关于Java包装类缓存的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 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动态主题处理入门:新手必读指南