创建一个新的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
答案 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中被弃用了。
<强>已过时即可。使用此构造函数很少是合适的。静态工厂
valueOf(int)
通常是更好的选择,因为它可能会产生明显更好的空间和时间性能。 [...]
<强>已过时即可。使用此构造函数很少是合适的。使用
parseInt(String)
将字符串转换为int
原语,或使用valueOf(String)
将字符串转换为Integer
对象。 [...]
为了完整起见,这是Integer.valueOf(int i)
的部分:
返回表示指定
Integer
值的int
实例。如果不需要新的Integer
实例,则通常应优先使用此方法,而不是构造函数Integer(int)
,因为此方法可能通过缓存频繁请求的值来显着提高空间和时间性能。此方法将始终缓存-128
到127
范围内的值,并且可以缓存此范围之外的其他值。
编辑1:感谢@VGR提及
Integer p = 1;
等同于
Integer p = Integer.valueOf(1);
但是,这仅适用于int
- -128
和127
之间的值。行为在JLS §5.1.7:
[...]如果装箱的值
的情况p
是评估类型boolean
,char
,short
的常量表达式(第15.28节)的结果,int
或long
,结果为true
,false
,'\u0000'
到'\u007f'
范围内的字符,或整数在-128
到127
范围内,让a
和b
成为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(包括),并可以缓存其他值 超出此范围。