新整数(123)、整数.valueOf(123)和仅123之间的差异

2022-09-01 07:37:49

Recenlty 我看到了这样的代码(Java):

myMethod(new Integer(123));

我目前正在重构一些代码,Sonar工具中有一个提示,即像这样使用sth更有利于内存:

myMethod(Integer.valueOf(123));

但是在这种情况下,我认为如果我使用:

myMethod(123);

我可以理解,如果我将一个变量传递给方法,但是硬编码的int?或者如果有长/双等,我想要数字的长表示。但是整数呢?


答案 1

new Integer(123)将为每个调用创建一个新实例。Object

根据javadoc,它有区别,它缓存对象...因此,如果您多次调用它,您可能会(或可能不会)以相同的方式结束。Integer.valueOf(123)Object

例如,以下代码:

   public static void main(String[] args) {

        Integer a = new Integer(1);
        Integer b = new Integer(1);

        System.out.println("a==b? " + (a==b));

        Integer c = Integer.valueOf(1);
        Integer d = Integer.valueOf(1);

        System.out.println("c==d? " + (c==d));

    }

具有以下输出:

a==b? false
c==d? true

至于使用值,您使用的是基元类型(考虑到您的方法也在其签名上使用基元类型) - 它将使用略少的内存并且可能更快,但是例如,您不会将其添加到集合中。int

如果你的方法的签名使用,也看看Java的AutoBoxing - 当它使用时,JVM会自动调用你(因此也使用缓存)。IntegerInteger.valueOf()


答案 2

public static Integer valueOf(int i)

返回一个 Integer 实例,该实例表示指定的 int 值。如果不需要新的 Integer 实例,则通常应优先使用此方法而不是构造函数 Integer(int),因为此方法可能会通过缓存频繁请求的值来显著提高空间和时间性能。

参数:
- 整型值。
返回:
表示 的整数实例。
起始时间:
1.5iai

参考 http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html#valueOf%28int%29

valueOf 的这个变体在 JDK 5 中被添加到 Byte、Short、Integer 和 Long(自 JDK 1.4 以来,它就已经存在于布尔值的平凡案例中)。当然,所有这些都是Java中不可变的对象。过去,如果你需要一个来自 int 的 Integer 对象,你就会构造一个新的 Integer。但是在 JDK 5+ 中,您确实应该使用 valueOf,因为 Integer 现在缓存在 -128 和 127 之间的 Integer 对象,并且每次都可以将完全相同的 Integer(0) 对象递回给您,而不是将对象构造浪费在全新的相同 Integer 对象上。

private static class IntegerCache {
private IntegerCache(){}

static final Integer cache[] = new Integer[-(-128) + 127 + 1];

static {
    for(int i = 0; i < cache.length; i++)
    cache[i] = new Integer(i - 128);
}
}

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);
}

请参阅为什么您应该使用 Integer.valueOf(int)

编辑

自动装箱和对象创建:

我们必须考虑的重要一点是,自动装箱不会减少对象创建,但它会降低代码复杂性。一个好的经验法则是在不需要对象的情况下使用基元类型,原因有两个:

基元类型不会比其相应的包装类型慢,并且可能快得多。可能存在一些涉及 == (比较引用) 和 .equals() (比较值) 的意外行为。

通常,当基元类型被装箱到包装器类型中时,JVM 会分配内存并创建一个新对象。但对于某些特殊情况,JVM 重用相同的对象。

以下是存储为不可变对象的基元列表:

  • 布尔值真和假

  • 所有字节值

  • 介于 -128 和 127 之间的短值

  • 介于 -128 和 127 之间的整型值

  • 字符在 \u0000 到 \u007F 范围内

推荐 http://today.java.net/pub/a/today/2005/03/24/autoboxing.html#performance_issue