【问题标题】:Wrapping primitives using the new operator vs wrapping primitives using valueOf使用 new 运算符包装基元与使用 valueOf 包装基元
【发布时间】:2009-11-25 20:55:00
【问题描述】:

有什么区别,

Integer i = new Integer("42");

Integer i = Integer.valueOf("42");

谢谢。

【问题讨论】:

    标签: java wrapper


    【解决方案1】:

    没有,看一下Integer.java:

    public static Integer valueOf(String s) throws NumberFormatException {
        return new Integer(parseInt(s, 10));
    }
    

    另外,JavaDoc

    【讨论】:

    • 虽然奇​​怪的是注意到 this 和 Integer.valueOf(Integer.parseInt(s)) 之间存在差异...由于某些奇怪的原因 valueOf(String) 不会递归到 valueOf( int),它内置了一些实例缓存。很奇怪。
    • 如果没有区别那为什么会有两种方式呢?
    • 它们有一些小的区别
    • @Rohit:没有区别,但我们不应该知道 :) 这是一个实现细节。
    【解决方案2】:

    使用new 非常明确地要求每次出现都创建一个新对象。

    使用工厂模式 (valueOf) 使实现有机会(它不需要接受)从缓存中提供已经创建的实例。

    我听说一些实现缓存了前 100 个左右的整数,因为它们出现的频率足够高,因此可以得到回报。

    最有用的情况是Boolean。我们知道只有两个可能的不同值,因此valueOf 总是返回这两个值之一,而无需创建新对象的开销。将 new 与布尔值一起使用是合法的,但总是会在性能和内存使用方面产生开销。

    【讨论】:

    【解决方案3】:

    查看源代码我们可以看出没有区别。

    前者使用构造函数显式创建一个新整数。

    后者使用工厂方法(结果调用构造函数)创建一个整数。

    第二个调用第一个的事实是一个实现细节,不一定在所有实现中都是如此,在某些情况下它可能不调用构造函数而是使用缓存(如valueOf( int i ) )

    生成的 Integer 在两种情况下的行为完全相同相同。

    然而,没有什么能阻止将第二个更改为:

    public static Integer valueOf(String s, int radix) throws NumberFormatException {
            return valueOf( parseInt( s, radix ));// which uses the cache
     }
    

    可以在下一个版本中执行该更改(或者某些 VM 可能会这样做),并且您的代码将在升级中“自动”获取它,而另一方面,使用您不能使用的构造函数,因为好吧,您正在显式调用构造函数。

    【讨论】:

      猜你喜欢
      • 2019-09-01
      • 1970-01-01
      • 2017-05-04
      • 1970-01-01
      • 2021-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多