Java 新的整数与值

Java 新的整数与值,java,sonarqube,Java,Sonarqube,我曾经使用过使我的代码更干净,它指出我使用的是新整数(1)而不是Integer.valueOf(1)。因为valueOf似乎没有实例化新对象,所以内存更友好。valueOf如何不实例化新对象?它是如何工作的?对于所有整数都是这样吗?Integer.valueOf为值-128到+127实现缓存。请参阅Java语言规范的最后一段,第5.1.7节,其中解释了装箱的要求(通常根据.valueOf方法实现) 来自: 公共静态整数值(int i) 返回表示指定int值的整数实例。如果不需要新的整数实例,通常

我曾经使用过使我的代码更干净,它指出我使用的是
新整数(1)
而不是
Integer.valueOf(1)
。因为
valueOf
似乎没有实例化新对象,所以内存更友好。
valueOf
如何不实例化新对象?它是如何工作的?对于所有整数都是这样吗?

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

来自:

公共静态整数值(int i) 返回表示指定int值的整数实例。如果不需要新的整数实例,通常应优先使用该方法而不是构造函数整数(int),因为通过缓存频繁请求的值,该方法可能会产生显著更好的空间和时间性能

ValueOf
通常用于自动装箱,因此(用于自动装箱时)至少缓存-128到127之间的值,以符合自动装箱规范

以下是Sun JVM 1.5实现的
值。?看看整个类,看看缓存是如何初始化的

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);
}
公共静态整数值(int i){
最终整数偏移=128;

如果(i>=-128&&i他们强迫您使用
valueOf()
而不是
newinteger()
,那么方法
valueOf()是
为您执行此操作,并缓存该值,以防您将来再次获得相同的数字。在这种情况下,该方法不会恢复新的整数,但会为您提供缓存的整数,这将使新整数的“创建”过程更快且内存友好


这样,如果您是没有经验的java程序员,您可能会给自己带来很多问题,因为您会得出
Integer.valueOf(342)==Integer.valueOf(342)
,因为您可能(也可能不会)对于两个整数使用相同的指针,您可能会以某种方式练习它,比如说,您在C#中学习过,这样会不时显示错误,您将不知道这些错误是如何从java.lang.Integer源代码中产生的。

。整数缓存是可配置的。要配置除Sun之外的整数缓存大小,我们不需要o根据源代码使用系统属性
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() {}
}
/**
*缓存以支持之间值的自动装箱的对象标识语义
*-JLS要求的128和127(含)。
*
*缓存在第一次使用时初始化
*getAndRemoveCacheProperties方法可用于获取和删除任何系统
*配置缓存大小的属性。此时
*缓存可能由vm选项-XX:AutoBoxCacheMax=控制。
*/
//java.lang.Integer.IntegerCache.high属性的值(在VM初始化期间获得)
私有静态字符串integerCacheHighPropValue;
静态void getAndRemoveCacheProperties(){
如果(!sun.misc.VM.isBooted()){
Properties props=System.getProperties();
整数CacheHighPropValue=
(String)props.remove(“java.lang.Integer.IntegerCache.high”);
if(integerCacheHighPropValue!=null)
System.setProperties(props);//从系统props中删除
}
}
私有静态类整型缓存{
静态最终int高;
静态最终整数缓存[];
静止的{
最终整数下限=-128;
//高值可由属性配置
int h=127;
if(integerCacheHighPropValue!=null){
//在此处使用Long.decode以避免调用
//需要初始化Integer的自动装箱缓存
int i=Long.decode(integerCacheHighPropValue).intValue();
i=数学最大值(i,127);
//最大数组大小为整数。最大值为
h=数学最小值(i,整数最大值--low);
}
高=h;
缓存=新整数[(高-低)+1];
int j=低;
for(int k=0;k
从java.lang.Short、java.lang.Byte和java.lang.Long创建127到-128的缓存

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));
    }
}
私有静态类LongCache{
私有长缓存(){
}
静态最终长缓存[]=新长缓存[-128)+127+1];
静止的{
for(int i=0;i
我知道,它在解装箱中的某个地方,但我可以找到该部分。感谢该部分没有明确说明valueOf。装箱通常是根据valueOf实现的,但这不是必需的。此外,它还允许缓存该范围以外的值。这只是装箱的最小范围。为了完整性,还需要请注意,在Sun VM上,缓存的最大值是用户可以使用
-XX:AutoBoxCacheMax=…
@MarkPeters进行配置的,以获得额外的完整性;-)该功能仅在Sun Java 6最近更新(我认为更新14左右)后才可用。注意:如果使用autoboxing,它将为您使用Integer.valueOf(int)。