Java Integer 常量池

Integer类

Integer 类在对象中包装了一个基本类型 int 的值。Integer 类型的对象包含一个 int 类型的字段。
    此外,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法。
Integer i = 10 和 Integer j = new Integer(10) 的区别
Java Integer 常量池Java Integer 常量池
1 1.publicstaticvoid main(String[] args){
2 2.Integer i=10;
3 3.Integer j=newInteger(10);
4 4.System.out.println(i==j);
5 5.}
View Code

编译上面的代码,我们利用反编译工具查看:

Java Integer 常量池Java Integer 常量池
1 public class Test {
2   public static void main(String[] args) {
3     Integer i = Integer.valueOf(10);
4     Integer j = new Integer(10);
5     System.out.println(i == j);//false
6   }
7 }
View Code

由此可见,当我们使用Integer i=10;创建一个Integer时,实际上底层调用的是Integer.valueOf(10);

Integer.valueOf()

关于这个方法,JDK中是这样说的:
public static Integer valueOf(int i)
返回一个表示指定的 int 值的 Integer 实例。如果不需要新的 Integer 实例,则通常应优先使用该方法,而不是构造方法 Integer(int),因为该方法有可能通过缓存经常请求的值而显著提高空间和时间性能。


参数:

i - 一个 int 值。
返回:
表示 i 的 Integer 实例。
从以下版本开始:
1.5
这个方法总是缓存了-128到127之间的值,还有,它也可以缓存这个范围之外的值。
为了说明这个问题,让我们来看看Integer.valueOf()的源代码:
Java Integer 常量池Java Integer 常量池
1 public static Integer valueOf( int i) {  
2     assert IntegerCache. high >= 127;  
3     if (i >= IntegerCache. low && i <= IntegerCache. high )  
4         return IntegerCache. cache[i + (-IntegerCache. low)];  
5     return new Integer(i);  
6 }  
View Code

这里的IntegerCache实际上是Integer 一个静态内部类:

 

Java Integer 常量池Java Integer 常量池
 1 private static class IntegerCache {
 2         static final int low = -128;
 3         static final int high;
 4         static final Integer cache[];
 5         static {
 6             // high value may be configured by property
 7             int h = 127;
 8             String integerCacheHighPropValue =
 9                 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
10             if (integerCacheHighPropValue != null) {
11                 int i = parseInt(integerCacheHighPropValue);
12                 i = Math.max(i, 127);
13                 // Maximum array size is Integer.MAX_VALUE
14                 h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
15             }
16             high = h;
17             cache = new Integer[(high - low) + 1];
18             int j = low;
19             for(int k = 0; k < cache.length; k++)
20                 cache[k] = new Integer(j++);
21         }
22         private IntegerCache() {}
23     }
View Code

 

通过上面的代码,我们可以很清楚的看到,当我们在-128到127这个范围内调用valueof()这个函数时,实际上使用的是缓存(IntegerCache)里面的值。

    IntegerCache是帮助我们缓存Integer的类。缓存数值的大小是由-XX:AutoBoxCacheMax= <size>来控制,或者可以通过系统属性来获得:-Djava.lang.Integer.IntegerCache.high=<size>
换句话来说,当我们通过以下方式创建Integer类:
Java Integer 常量池Java Integer 常量池
1 Integer int1=10;
2 Integer int2=Integer.valueOf(10);
View Code

会获得在缓存池上相同的实例

所以如果值在-128到127之间,你使用valueof()将获得相同的引用,超过这个范围将返回new Integer(int)。因为是相同的引用,在-128到127范围内你的==操作是有用的。
 Java缓存了-128到127范围内的Integer类。所以当你给这个范围的封装类赋值时,装箱操作会调用Integer.valueOf() 函数,反过来就会给封装类赋上一个缓存池实例的引用。
另一方面来说,如果用超出这个范围的值给封装类赋值时,Integer.valueOf()会创建一个新的Integer类。因此,比对超出这个范围的Integer类时,会返回false。
Java Integer 常量池
同理,Short、Byte、Long也缓存-128到127之间的数值。



转载于:https://www.cnblogs.com/yaoyinglong/articles/4098292.html