【问题标题】:Difference between Long.valueOf(java.lang.String) and new Long(java.lang.String)?Long.valueOf(java.lang.String) 和 new Long(java.lang.String) 的区别?
【发布时间】:2012-10-30 18:17:33
【问题描述】:

我正在合并由两个不同的人编写的代码,并注意到将 String 值转换为 Long 有两种不同的方式。

Coder #1 已经这样做了:

String strId = "12345678";
...
Long lId = new Long(strId);

虽然 2 号编码器已经这样做了:

String strId = "12345678";
...
Long lId = Long.valueOf(strId);

在功能上,代码的运行方式完全相同。每个位周围都有一个 try/catch 块来处理任何抛出的NumberFormatException。传入的字符串值是一个代表小数的 8 位字符串:"12345678",并且在这两种情况下都正确转换为 Long

在构造函数中传递字符串和使用 Long.valueOf() 有什么功能上的区别吗?我在这里检查了构造函数文档:

Long(java.lang.String)

这里还有 valueOf() 的文档:

Long.valueOf(java.lang.String)

据我所知,它们都调用 parseLong() 所以使用哪个并不重要。我只是想确保我不会为以后的一些奇怪行为做好准备。另外,哪种风格比另一种更“正确”(哈哈)?

【问题讨论】:

    标签: java coding-style long-integer


    【解决方案1】:

    区别在于使用new Long()总是会创建一个新对象,而使用Long.valueOf(),如果值在[-128 to 127]之间,可能会返回long的缓存值.

    所以,你应该更喜欢Long.valueOf 方法,因为它可以节省一些内存。

    如果您看到Long.valueOf(String) 的源代码,它会在内部调用Long.valueOf(long),我将其源代码贴在下面:-

    public static Long valueOf(String s) throws NumberFormatException
    {
        return Long.valueOf(parseLong(s, 10));
    }
    
    public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache 
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }
    

    【讨论】:

    • 这正是我在查找此之前所理解的grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/… 能否请您分享源链接。
    • @ArunManivannan..可以在jdk安装目录下找到源码。转到C:\Program Files\Java\jdk 会有一个src 文件夹。可能是压缩格式。解压它。前往java -&gt; lang -&gt; Long.class查看源代码。
    • 这很有帮助,感谢代码 sn-p 和解释。
    • @torgis。别客气 :)。每当您对某种方法有疑问时。请记住,您总是需要检查源代码。在您的JDK 安装目录中。您只需要知道要在其中搜索的相应包名称即可。
    • 它可能会节省内存,但通常会浪费处理器时间
    【解决方案2】:

    Long.valueOf() 应该是首选:它为一些常用值返回 Long 的缓存值,而不是像构造函数那样构造一个新实例。

    即使某些 Java 版本不使用缓存,使用valueOf() 也可以在未来的版本中实现,而构造函数将始终创建一个新实例。

    【讨论】:

    • 具体取值范围为[-128 to 127]。但是,我认为这是可以改变的。不知道具体是怎么回事。
    【解决方案3】:

    意思是一样的

    public static Long valueOf(String s) throws NumberFormatException{
            return new Long(parseLong(s, 10));
    }
    
    public Long(String s) throws NumberFormatException {
        this.value = parseLong(s, 10);
    }
    

    Source JDK 6.0

    【讨论】:

    • 阿伦,如果 s 超出某个范围(-128 t0 127),它们是相同的,如果 s 在范围内,它们是不一样的。
    • 您使用的是哪个版本的 Java?在我的 Java 6 和 7 版本中,使用了缓存。
    • @Nambari 我也这么认为。然而,实现令人惊讶。
    • @JBNizet 感谢您的来信。 6.0。相应地编辑了帖子。
    • 即使在 JDK 6 中,它们的字面意思也不相同;他们只是碰巧有同样的行为。它们的含义由 Javadoc 定义。
    【解决方案4】:

    两者都在内部执行parseLong(String, int)(int 是基数,值为 10),但valueOf 具有如下所述的优势:

    If a new Long instance is not required, this method should generally be used in preference to the constructor Long(long), as this method is likely to yield significantly better space and time performance by caching frequently requested values.

    【讨论】:

      【解决方案5】:

      这是在 eclipse 上运行的 PMD 插件输出

      我检查的代码是

      Long l = new Long("123456");
      

      在 JDK 1.5 中,调用 new Long() 会导致内存分配。 Long.valueOf() 对内存更友好。

      【讨论】:

        【解决方案6】:

        我正在考虑如何为我们的应用程序更改缓存的范围和大小,用 Longs 重载;

        j2se api 不支持此类更改 一种方法是使用 ClassLoader 甚至使用 JVMTI 更改加载的 java 字节码 (它允许将此类技巧排除在项目之外,例如外部调整)

        或者,可能是,创建外部缓存和自己的静态 cachedValueOf() 这是直截了当的,但是取决于某些非应用程序需求的代码并不好

        【讨论】:

        • 是回答问题吗?您应该使用question 选项来提问。
        猜你喜欢
        • 2022-11-04
        • 2021-09-01
        • 2021-11-25
        • 1970-01-01
        • 1970-01-01
        • 2013-11-25
        • 2015-04-01
        • 2021-04-22
        • 2020-02-27
        相关资源
        最近更新 更多