新整数与valueOf

我使用Sonar来使我的代码更清洁,并指出我正在使用new Integer(1)而不是Integer.valueOf(1) 。 因为看起来valueOf没有实例化一个新的对象,所以对内存更友好。 valueOf如何不能实例化一个新的对象? 它是如何工作的? 这对所有整数都是如此吗?

Integer.valueOf为值-128到+127实现caching。 请参阅Java语言规范第5.1.7节的最后一段,它解释了装箱的要求(通常以.valueOf方法实现)。

http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

从JavaDoc :

public static Integer valueOf(int i)返回一个Integer实例,表示指定的int值。 如果不需要新的Integer实例,则通常应优先使用此方法,而不是构造函数Integer(int),因为通过caching频繁请求的值,此方法可能会产生显着更好的空间和时间性能。

ValueOf通常用于自动装箱,因此(用于自动装箱时)至less要caching-128到127的值,以遵循自动装箱规范。

这里是Sun JVM 1.5的valueOf实现。 看看整个类,看看如何初始化caching。

 public static Integer valueOf(int i) { final int offset = 128; if (i >= -128 && i <= 127) { // must cache return IntegerCache.cache[i + offset]; } return new Integer(i); } 

他们推动你使用valueOf()而不是new Integer()所以方法的valueOf()为你做,并caching的值,以防你将来再次获得相同的数字。 在这种情况下,方法不会安装新的整数,但会给你caching的,将使新的整数的“创造”更快和内存友好的过程。

这样,如果你是一个没有经验的java程序员,你可能会导致你很多问题,因为你可能会得出结论Integer.valueOf(342)==Integer.valueOf(342) ,因为你可能(或不可能)有两个整数,也许你会用某种方式来练习它,比如说,你用C#学到的东西,这样就会不时地向你展示错误,而你不知道这些错误是从哪里来的。

从java.lang.Integer源代码。 整数caching是可configuration的。 要configurationSun以外的Integercaching大小,我们需要根据源代码使用System属性java.lang.Integer.IntegerCache.high

 /** * 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. During VM initialization the * getAndRemoveCacheProperties method may be used to get and remove any system * properites that configure the cache size. At this time, the size of the * cache may be controlled by the vm option -XX:AutoBoxCacheMax=<size>. */ // value of java.lang.Integer.IntegerCache.high property (obtained during VM init) private static String integerCacheHighPropValue; static void getAndRemoveCacheProperties() { if (!sun.misc.VM.isBooted()) { Properties props = System.getProperties(); integerCacheHighPropValue = (String)props.remove("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) System.setProperties(props); // remove from system props } } 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() {} } 

从java.lang.Short,java.lang.Byte和java.lang.Long创build一个127到-128的caching

 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); } } private static class ShortCache { private ShortCache() { } static final Short cache[] = new Short[-(-128) + 127 + 1]; static { for (int i = 0; i < cache.length; i++) cache[i] = new Short((short) (i - 128)); } } private static class ByteCache { private ByteCache() { } static final Byte cache[] = new Byte[-(-128) + 127 + 1]; static { for (int i = 0; i < cache.length; i++) cache[i] = new Byte((byte) (i - 128)); } }