小编典典

创建一个持有值1的新Integer对象?

java

要创建一个新的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

阅读 224

收藏
2020-11-01

共2个答案

小编典典

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

Integer p = Integer.valueOf(1);

此模式称为Factory方法模式。有人可能会问这种方法有什么好处。幸运的是,classInteger实现是开源的,因此让我们看一下:

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

似乎存在某种Integer-value缓存。如果请求一个Integer具有缓存范围内的值的Java,则Java不会创建新对象,而是返回先前创建的对象。这Integer是可行的,因为s是不可变的。甚至可以使用system属性来控制高速缓存上限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之间的-128-值127。该行为在JLS§5.1.7中定义:

[…]如果该值p被装箱是评价类型的常量表达式(§15.28)的结果booleancharshortint,或long,其结果是truefalse在的范围内的字符'\u0000',以'\u007f'包容,或在范围内的整数-128127包容性的,然后让ab是任意两个装箱转换的结果p。总是这样的a == b


虽然不在JLS中,但javac我正在使用(9.0.4)的版本确实将装箱压缩到了AdamRosenfieldInteger.valueOf(...);在此答案中所示的位置。

2020-11-01
小编典典

Integer p = Integer.valueOf(1);建议使用方法4 。JavaDoc说:

返回表示指定int值的Integer实例。如果不需要新的Integer实例,则通常应优先于构造方法Integer(int)使用此方法,因为此方法通过缓存经常请求的值可能会产生明显更好的空间和时间性能。此方法将始终缓存-128至127(包括)范围内的值,并且可能缓存该范围之外的其他值。

2020-11-03