创建一个包含值1的新Integer对象?

时间:2018-04-18 16:37:16

标签: java object integer

创建一个新的Integer对象,该对象保存java 1中的值,其中一个是正确的,以下方法的差异究竟是什么,因为所有打印值?

方法1:

 Integer p = new Integer(1);

方法2:

Integer p = 1;

方法3:

Integer p = new Integer("1");

使用方法三我收到以下警告:

Note: HelloWorld.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details

2 个答案:

答案 0 :(得分:3)

您跳过了预期的解决方案:

Integer p = Integer.valueOf(1);

此模式称为Factory method pattern。您可能会问这种方法的好处是什么。幸运的是,类Integer的实现是开源的,所以让我们来看看:

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

似乎有某种Integer - 值缓存。如果请求Integer的值在缓存范围内,则Java不会创建新对象,而是返回先前创建的对象。这是有效的,因为Integer是不可变的。您甚至可以使用系统属性java.lang.Integer.IntegerCache.high=...来控制缓存上限。

为什么另外两种创建Integer的方法会产生警告?因为它们在Java 9中被弃用了。

Integer#Integer(int value)

  

<强>已过时即可。使用此构造函数很少是合适的。静态工厂valueOf(int)通常是更好的选择,因为它可能会产生明显更好的空间和时间性能。 [...]

Integer#Integer(String s)

  

<强>已过时即可。使用此构造函数很少是合适的。使用parseInt(String)将字符串转换为int原语,或使用valueOf(String)将字符串转换为Integer对象。 [...]

为了完整起见,这是Integer.valueOf(int i)的部分:

  

返回表示指定Integer值的int实例。如果不需要新的Integer实例,则通常应优先使用此方法,而不是构造函数Integer(int),因为此方法可能通过缓存频繁请求的值来显着提高空间和时间性能。此方法将始终缓存-128127范围内的值,并且可以缓存此范围之外的其他值。

编辑1:感谢@VGR提及

Integer p = 1;

等同于

Integer p = Integer.valueOf(1);

但是,这仅适用于int - -128127之间的值。行为在JLS §5.1.7

中定义
  

[...]如果装箱的值p是评估类型booleancharshort的常量表达式(第15.28节)的结果, intlong,结果为truefalse'\u0000''\u007f'范围内的字符,或整数在-128127范围内,让ab成为p任意两次拳击转化的结果。始终是a == b

的情况

编辑2:感谢@TobiasWeimer,他引起了我的注意。

虽然不在JLS中,我使用的javac版本(9.0.4)确实将装箱编译为Integer.valueOf(...);,如this answer所示。< / p>

答案 1 :(得分:1)

方法4,推荐使用Integer p = Integer.valueOf(1);。 JavaDoc说:

  

返回表示指定int值的Integer实例。如果一个   新的Integer实例不是必需的,这个方法一般应该是   优先使用构造函数Integer(int),就像这个方法一样   可能会产生明显更好的空间和时间表现   缓存频繁请求的值。此方法将始终缓存   值范围为-128到127(包括),并可以缓存其他值   超出此范围。