24

我对 PMD 规则有疑问Avoid instantiating new objects inside loops。这是一些示例代码:

import java.awt.Dimension;

public class PMDDemo {
    public static void main(final String[] args) {
        final Dimension[] arr = new Dimension[10];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new Dimension(i, i); // rule violation here
        }
    }
}

PMD 在代码中的标记位置给了我上面提到的违反规则的行为。我应该如何创建一个类的n 个实例而不在循环中创建它们?

我知道 PMD 的一些规则是有争议的(比如onlyOneExit规则)。但到现在为止,我至少明白了他们背后的想法。我不明白这条规则背后的原因。有人可以帮我吗?

4

2 回答 2

28

对于您的特定用例,在循环之后保留对新对象的引用是没有意义的。因此,您的解决方案没有真正的替代方案。

更一般地说,在 Java 中创建短期对象很便宜*(除了 GC 将更频繁地运行的隐藏成本)。特别是分配几乎是免费的,GC 的时间主要取决于可到达对象的数量——对于典型的 GC 算法,死对象不会增加 GC 时间。

如果 JIT 检测到创建了不必要的对象,它还可以执行各种优化。

显然,创建无用的做法不是推荐的做法,但尝试重用对象往往适得其反。

作为一个实际的例子,你可以看看这篇文章,它表明在循环中创建一个新集合比在循环之前创建一个并在每次迭代中清除它更便宜。

* 感谢@RichardTingle 提供链接

于 2013-07-03T21:36:05.757 回答
-1
for (int i = 0; i < arr.length; i++) {
  arr[i] = new Dimension(i, i); // rule violation here
}

上述 Pmd 可以通过以下方式解决

 for (int i = 0; i < arr.length; i++) {
   arr[i] = createNewDimension(i,i); // rule violation here
 }

 private static Dimension createNewDimension(i,i) {
   return new Dimension(i, i);
 }

我们不应该直接在循环中使用 new 运算符,只需将其移动到私有方法中即可。

于 2016-12-01T21:23:41.730 回答