1、Integer类的高速缓存
(1)声明两个Integer类型的变量,然后用==比较是否是一个对象
public class Test { public static void main(String[] args) { Integer integer1=127; Integer integer2=127; System.out.println(integer1==integer2); Integer integer3=128; Integer integer4=128; System.out.println(integer3==integer4); } }
true false
按照java中==的语法规则,==是比较两个对象是否相等,也就是对象的引用指向的内存地址是否相等。我们在看第一个127的时候能够很容易地理解,但是在看到128的时候就不知道为什么了,两个数字只相差一就不行了。
(2)查看Integer类的源码
断点调试查看运行情况的话,会发现最先进入的是Integer类的valueOf方法:
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 property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try {
进一步查看源码可以看到一个内部私有类,该类缓存了从-128到127之间的所有的整数对象,如果值在-128到127之间,那么他就可以直接从高速缓存返回实例。这也就是为什么127返回true,而128返回false的原因。
通过源码可以看到下界已经确定了,但是上界并没有确定,默认情况下是127,但是我们可以通过虚拟机指令来更改上界
(3)Integer类高速缓存的好处
使用到数值较小的整数的概率要比使用整数数值加大的概率要高很多,因此,使用高速缓存,将Integer类型不同的对象引用指向同一对象可以减少内存的占用
2、直接使用new的方式声明Integer类型的变量不具有高速缓存机制
(1)代码
public class Test { public static void main(String[] args) { Integer integer1=new Integer(127); Integer integer2=new Integer(127); System.out.println(integer1==integer2); Integer integer3=new Integer(128); Integer integer4=new Integer(128); System.out.println(integer3==integer4); } }
false false
(2)通过断点调试可以见到new方式声明变量并不会调用Integer类的valueOf方法,而是调用了Integer类的构造方法
public Integer(int value) { this.value = value; }
因此,是不会用到Integer类的高速缓存的
3、其他具有缓存机制的类
(1)具有缓存机制的类
Byte,Short,Integer,Long为 -128 到 127
Character范围为 0 到 127
(2)以Long为例
public class Test { public static void main(String[] args) { Long long1=127l; Long long2=127l; System.out.println(long1==long2); Long long3=128l; Long long4=128l; System.out.println(long3==long4); } }
true false
查看源码:
public static Long valueOf(long l) { final int offset = 128; if (l >= -128 && l <= 127) { // will cache return LongCache.cache[(int)l + offset]; } return new Long(l); }
private static class LongCache { private LongCache(){} static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } }
除了Integer可以指定缓存范围,其它类都不能。
总结:
使用到数值较小的整数的概率要比使用整数数值加大的概率要高很多,因此,使用高速缓存可以减少内存占用
具有缓存机制的类:Byte,Short,Integer,Long为 -128 到 127。Character范围为 0 到 127
除了Integer可以指定缓存范围(只能指定上限),其它类都不能