【问题标题】:The "Why" behind PMD's StringInstantiation rulePMD 的 StringInstantiation 规则背后的“为什么”
【发布时间】:2013-01-02 14:11:56
【问题描述】:

按照现有线程The “Why” behind PMD's rules 的思路,我试图找出一个特定 PMD 规则的含义:String and StringBuffer Rules.StringInstantiation

此规则规定您不应显式实例化 String 对象。根据他们的手册页:

避免实例化 String 对象;这通常是不必要的,因为 它们是不可变的,可以安全地共享。

此规则由以下 Java 定义 类:net.sourceforge.pmd.lang.java.rule.strings.StringInstantiationRule

示例:

私有字符串 bar = new String("bar"); // 只做一个字符串 bar = “酒吧”;

http://pmd.sourceforge.net/pmd-5.0.1/rules/java/strings.html

除了毫无意义之外,我看不出这种语法有什么问题。它会影响整体性能吗?

感谢您的任何想法。

【问题讨论】:

  • 感谢大家的回答。所以基本上 1)它更慢 2)它使代码更难阅读(除了一些故意完成的情况)

标签: java code-analysis pmd


【解决方案1】:

使用String foo = "foo" 将在 PermGen 空间中存在“foo”实例(这被称为 字符串实习)。如果您稍后输入String bar = "foo",那么 PermGen 空间中仍然只有一个“foo”。

写入String foo = new String( "foo" ) 还将创建一个String 对象以计入堆。

因此,存在防止浪费内存的规则。

干杯,

【讨论】:

    【解决方案2】:

    它通常不会以任何可衡量的方式影响性能,但是:

    private String bar = new String("bar"); // just do a String bar = "bar";
    

    如果你执行这一行一百万次,你将创建一百万个对象

    private String bar = "bar"; // just do a String bar = "bar";
    

    如果你执行这一行一百万次,你将创建一个对象。

    在某些情况下,这实际上会产生影响。

    【讨论】:

      【解决方案3】:

      它会影响整体性能吗?

      嗯,性能和维护。做一些毫无意义的事情会让读者想知道为什么代码一开始就在那里。当那个无意义的操作涉及创建新对象(在这种情况下是两个 - 一个新的char[] 和一个新的String)时,这是避免它的另一个原因......

      过去,如果现有字符串最初是作为较长字符串的一个小子字符串获得的 - 或以其他方式获得由大字符数组。我相信最近的 Java 实现并非如此,但显然您仍然可以使用旧的实现。无论如何,这对于 constant 字符串应该不是问题,请注意。

      (您可以争辩说,创建一个新对象允许您对其进行同步。不过,我会避免从字符串开始同步。)

      【讨论】:

      • 不,在我的例子中,这种语法的目的不是针对较旧的 Java 实现的软运行。感谢您提供详细信息。
      【解决方案4】:

      一个区别是内存占用:

      String a = "abc"; //one object
      String b = "abc"; //same object (i.e. a == b) => still one object in memory
      String c = new String("abc"); // This is a new object - now 2 objects in memory
      

      说实话,我能想到的唯一原因是,为什么要使用 String 构造函数是与 substring 结合使用,它是对原始字符串的一种视图。在这种情况下使用 String 构造函数有助于摆脱不再需要的原始字符串。

      但是,从 java 7u6 开始,情况不再如此,所以我看不出有任何理由再使用它。

      【讨论】:

        【解决方案5】:

        它很有用,因为它创建了一个新的身份,有时对象身份对应用程序很重要/至关重要。例如,它可以用作内部哨兵值。还有其他有效的用例,例如避免常量表达式。

        如果初学者写这样的代码,很可能是一个错误。但这是一个非常短的学习期。任何有中等经验的 Java 程序员都不太可能错误地编写它。它必须用于特定目的。将其归档在“这看起来像是一个愚蠢的错误,但需要付出努力才能做到,所以它可能是故意的”。

        【讨论】:

          【解决方案6】:

          是的

          • 毫无意义
          • 令人困惑
          • 稍慢

          您应该尽量编写最简单、最清晰的代码。添加无意义的代码是不好的。

          【讨论】:

            猜你喜欢
            • 2011-01-31
            • 1970-01-01
            • 2010-12-09
            • 2015-09-13
            • 1970-01-01
            • 1970-01-01
            • 2018-02-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多