2012-09-06 22 views

回答

8

Java还具有对-128 to 127之间的小整数整数池,以便表现同样为整型也类似于字符串常量池的

你会发现下面的代码Integer

private static class IntegerCache { 
    static final int high; 
    static final Integer cache[]; 

    static { 
     final int low = -128; 

     // high value may be configured by property 
     int h = 127; 
     if (integerCacheHighPropValue != null) { 
      // Use Long.decode here to avoid invoking methods that 
      // require Integer's autoboxing cache to be initialized 
      int i = Long.decode(integerCacheHighPropValue).intValue(); 
      i = Math.max(i, 127); 
      // Maximum array size is Integer.MAX_VALUE 
      h = Math.min(i, Integer.MAX_VALUE - -low); 
     } 
     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() {} 
} 

另外,作为中陈述下面毒药回答:

Chapter 5. Conversions and Promotions

如果值p被装箱为真,假,一个字节或范围在\ u0000到\ u00f之间的字符,或者在-128到127之间的一个int或短数字,则让r1和r2为任何两个拳击转换的结果。 r1 == r2总是如此。

+0

JLS说*至少*值-128到127被缓存,而不是*到那个范围。它甚至在讨论段中说:“理想情况下,装箱一个给定的原始值p,总会产生相同的参考。实际上,使用现有的实现技术可能是不可行的......这将允许(但不要求)共享部分或全部这些参考文献。“ – yshavit

+0

@yshavit改为''之间' –

2

对象池是虚拟机和/或运行时环境的工件。他们可能出于性能原因出现在那里,但你绝不应该依赖他们。使用.equals()。

JLS指定拳击行为,正如在评论中指出的那样,这部分在Integer类本身中实现;然而,另一个有趣的说法是,即使这个池的大小可以通过VM参数调整。来自Integer.java:

585  /** 
586  * Cache to support the object identity semantics of autoboxing for values between 
587  * -128 and 127 (inclusive) as required by JLS. 
588  * 
589  * The cache is initialized on first usage. The size of the cache 
590  * may be controlled by the -XX:AutoBoxCacheMax=<size> option. 
591  * During VM initialization, java.lang.Integer.IntegerCache.high property 
592  * may be set and saved in the private system properties in the 
593  * sun.misc.VM class. 
594  */ 
+0

'Integer'汇集对象,而不是JVM –

+0

啊,这很有趣。所以,与Strings不太一样。 –

1

[5.1.7。拳击转换] http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html

被装箱值p为真,假,字节,或在范围\ u0000的一个char到\ u007f,或-128和127之间int或短号码(含),那么让r1和r2是p的任何两个装箱转换的结果。 r1 == r2总是如此。

但是总的来说,依靠这个将是愚蠢的,因为您首先必须检查该数字是否在缓存范围内,然后有条件地使用==或equals()。 使用==表示基本类型,Class和枚举,等于一切。