新Integer(123),Integer.valueOf(123)和123之间的差异

时间:2012-01-27 08:49:03

标签: java integer new-operator value-of

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

myMethod(new Integer(123));

我目前正在重构一些代码,Sonar工具中有一个提示,使用这样的内存更友好:

myMethod(Integer.valueOf(123));

但是在这种情况下,我认为如果我使用的话没有区别:

myMethod(123);

我能理解,如果我将变量传递给方法,但硬编码为int?或者,如果有长/双等,我想要长数字表示。但整数?

5 个答案:

答案 0 :(得分:32)

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

根据javadocInteger.valueOf(123)有不同之处,它会缓存对象...因此,如果您将其称为“{1}},则可能(或可能不会)结束相同的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值,你正在使用原始类型(考虑到你的方法也在其签名上使用原始类型) - 它将使用稍微少一点的内存并且可能更快,但你赢了&#39例如,可以将它添加到集合中。

如果您的方法签名使用Integer,请查看Java AutoBoxing - 使用它时,JVM会自动为您调用Integer.valueOf()(因此使用缓存以及。)

答案 1 :(得分:8)

  

<强> public static Integer valueOf(int i)

     

返回表示指定int值的Integer实例。如果不需要新的Integer实例,则此方法应该   通常优先使用构造函数Integer(int),as   这种方法可能会产生明显更好的空间和时间   通过缓存经常请求的值来实现性能。

     

参数:
     i - 一个int值    返回:
     a表示i的整数实例。
   因为:
     1.5

参考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)对象而不是浪费全新的对象构造相同的整数对象。

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

参考Why YOU should use Integer.valueOf(int)

修改

自动装箱和对象创建:

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

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

通常,当将基元类型装入包装类型时,JVM会分配内存并创建新对象。但是对于某些特殊情况,JVM会重用相同的对象。

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

  • 布尔值为true和false

  • 所有字节值

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

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

  • 在\ u0000到\ u007F

  • 范围内的字符

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

答案 2 :(得分:1)

int是原始类型,而不是对象。

new Integer(123)Integer.valueOf(123)都返回表示值123的Integer对象。根据Integer.valueOf()的javadoc:

  

返回表示指定int值的Integer实例。   如果不需要新的Integer实例,则通常应该使用此方法   优先使用构造函数Integer(int),就像这个方法一样   可能通过缓存产生明显更好的空间和时间性能   经常要求的价值观。

答案 3 :(得分:1)

您的方法是否需要intInteger

new Integer(int)Integer.valueOf(int)都返回Integer个对象,但valueOf应该是首选,因为它更有效,因为它返回缓存的对象。如果您的方法需要Integer,则应使用Integer.valueOf

如果您的方法需要int,则应使用int(例如123)。

但是,由于autoboxing而不是必须以这种方式匹配类型,因为{{3}}会自动将int转换为Integer,反之亦然。这样,您就可以将int传递给需要Integer的方法,并将Integer传递到需要int的方法中。但请注意,与自动装箱相关的性能成本。使用自动装箱的最常见示例是,如果要将基元存储在集合中。

答案 4 :(得分:1)

仅在-128到+127之间的范围内实现缓存。

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

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

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

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

 Integer e = Integer.valueOf(128);
 Integer f = Integer.valueOf(128);

 System.out.println("e==f? " + (e==f)); 

参考这个java规范:

http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7

在JDK 5+中,你应该使用valueOf,因为Integer现在可以在-128到127之间缓存Integer对象,并且可以每次都返回相同的Integer(0)对象,而不是在全新的相同上浪费对象构造整数对象。