PMD:避免在循环内实例化新对象

时间:2013-06-27 10:12:48

标签: java loops instantiation pmd

我遇到了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 规则)。但到目前为止,我至少理解了他们背后的想法。我不明白这条规则背后的原因。有人可以帮我吗?

2 个答案:

答案 0 :(得分:24)

对于您的特定用例,在循环之后保留对新Object 的引用是没有意义的。所以你的解决方案没有其他替代品。

更一般地说,creating short lived objects in Java is cheap *(除了GC将更频繁地运行的隐藏成本)。特别是,分配几乎是免费的,GC的时间主要取决于可达对象的数量 - 死对象不会增加典型GC算法的GC时间。

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

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

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

*感谢@RichardTingle提供链接

答案 1 :(得分:0)

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运算符,只需在私有方法中移动它。