2

根据现有线程,PMD 规则背后的“原因”,我试图找出一个特定 PMD 规则的含义:String 和 StringBuffer Rules.StringInstantiation

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

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

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

例子):

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

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

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

感谢您的任何想法。

4

6 回答 6

3

String foo = "foo"PermGen 空间中将会有一个“foo”的实例(这被称为字符串实习)。如果您稍后键入String bar = "foo",PermGen 空间中仍然只有一个“foo”。

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

因此,规则是为了防止浪费内存。

干杯,

于 2013-01-02T14:16:08.427 回答
3

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

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

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

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

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

在某些情况下,这实际上会有所作为。

于 2013-01-02T14:16:47.070 回答
3

它会影响整体性能吗?

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

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

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

于 2013-01-02T14:16:56.750 回答
2

一个区别是内存占用:

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 开始,情况不再如此,所以我看不出有任何理由再使用它。

于 2013-01-02T14:16:32.203 回答
2

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

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

于 2013-01-02T14:37:17.770 回答
1

这是

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

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

于 2013-01-02T14:22:40.857 回答