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

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

myMethod(new Integer(123)); 

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

 myMethod(Integer.valueOf(123)); 

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

 myMethod(123); 

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

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值,你正在使用原始类型(考虑到你的方法也在其签名上使用原始类型) – 它将使用稍微更少的内存并且可能更快,但你不会将它添加到集合中, 例如。

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

public static Integer valueOf(int i)

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

参数:
i – 一个int值。
返回:
表示i a整数实例。
以来:
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)对象交给你,而不是在一个全新的相同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重用相同的对象。

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

  • 布尔值true和false

  • 所有字节值

  • -128到127之间的短值

  • int值介于-128和127之间

  • char在\ u0000到\ u007F范围内

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

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

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

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

你的方法需要int还是Integer

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

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

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

缓存中只有-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)对象交给你,而不是在全新的相同Integer对象上浪费对象构造。