默认构造函数是善还是恶? Checkstyle和PMD在这里相反

时间:2010-10-26 13:08:53

标签: java checkstyle pmd

Checkstyle说:

Class should define a constructor.

PMD说:

Avoid unnecessary constructors - the compiler will generate these for you.

谁是对的?或者让我们这样说 - 在课堂上有一个空的默认ctor有什么优缺点?

9 个答案:

答案 0 :(得分:15)

我喜欢PMD的回答。代码越少越好。不要编写编译器为你编写的构造函数。

我的印象是编写构造函数的主要论点是,一些不了解构造函数如何在Java中工作的程序员可能会偶然发现代码并感到困惑。我不喜欢编写不必要的代码,但我不喜欢编写愚蠢的代码。

但这是我的痴迷,可能是不合理的。有一个应用程序程序员的世界,其重点是业务,而不是语言,谁不是语言专家。许多人使用的生存技术是具有一致的风格,是否绝对必要不是重点。

答案 1 :(得分:8)

正如许多“有争议”的决定一样,事实是它确实无关紧要。编写构造函数或不编写。对代码质量和可维护性的影响可以忽略不计。如果你正在和其他人一起编码,那么采用相同的风格来保持一致性,但是否则 - 无论你想做什么。

答案 2 :(得分:6)

当默认构造函数是唯一的构造函数时,它是100%相当于使用空体明确写入它或者省略它。但是,如果您有任何显式定义的构造函数,默认情况下,编译器将不会生成默认构造函数。这意味着如果您依赖编译器为您生成构造函数,并在以后添加替代构造函数,那么默认构造函数就会消失。就个人而言,无论如何,我倾向于让编译器完成这一代;如果该默认构造函数正在使用中,它将生成编译警告,并且在此时很容易添加。否则,为什么要保持它?

答案 3 :(得分:1)

虽然我有点像较小的代码但是使用默认构造函数可以在需要调试时更容易设置断点。

无论如何,我可以提醒你,PMD的网站也说这个问题是有争议的:)

答案 4 :(得分:1)

我会选择Checkstyle。没有明确的(noarg)构造函数,没有人会知道它是否有意。

考虑这个实用程序类:

public class Util {
    // no constructor given - implicit default constructor
    // intended? probably not, but who knows

    public static void foo() {
      // blabla
    }

    public static void bar() {
      // more blabla
    }

}

答案 5 :(得分:1)

默认情况下,编译器为您生成默认构造函数,因此如果您不想指定任何特殊操作(这里不是初始化成员),那么您不必指定构造函数。

其他事情是某些类应该具有一致的状态。例如,您有一个Book类。没有创建没有标题的书,因此有必要使用字符串参数指定构造函数:

public Book(String name) {
    this.name = name;
}

对于默认构造函数,如果要序列化类或在编组/解组中使用它们(JAXB需要一个空的默认构造函数),它们可能是必需的。

如果这不是重点,并且您的类没有所谓的一致状态,那么声明绝对不需要空的默认构造函数。

你应该记住,默认情况下默认构造函数是公共的,所以如果你想对它有一些限制,可以考虑去掉一个明确的构造函数。

此外,如果您的类很长,您可以考虑声明一个空的默认构造函数以提高可读性。

答案 6 :(得分:1)

IMO Class should define a constructor因为如果依赖于默认构造函数,实例变量将具有默认值(对于整数为零,对于String等为null)。如果要在创建该类的对象时将实例变量设置为某个默认值,则在这种情况下自定义构造函数可能是一个不错的选择。 (如果你不想使用getter& setter方法)

class Cube {
   private int length;
   private int breadth;
   private int height;

  public Cube() {
      length = 10;
      breadth = 10;
      height = 10;
  }
     ......
     ......
}

现在,当您创建类Cube1的对象时,该对象的所有实例varibales都将设置为10.如果您不在此处使用构造函数,则实例变量(length,widthth和height)将具有默认值(在这种情况下为零)。


编辑:[又增加了一件事]

如果您依赖编译器为您生成默认构造函数,并且您想使用一些从用户获取参数的构造函数,那么您必须定义默认构造函数,否则编译器将生成错误。

记住:只有当该类不包含任何其他构造函数时,编译器才会为您的类生成默认构造函数。

答案 7 :(得分:1)

我要补充的一点是,如果没有指定构造函数,则会有一个隐式的默认构造函数,代码可能依赖于它。

然后当你添加一个特定的构造函数时,代码可能不再编译 - 或者更糟糕的是,代码将不会运行(可能是对无参数构造函数的反射依赖 - 大多数ORM工具需要为持久化实体提供默认构造函数)。

如果需要,应该显式添加默认构造函数。

答案 8 :(得分:0)

我倾向于只在需要时编写代码。如果不需要任何其他构造函数,请让编译器为您生成它。否则,编写所需的所有构造函数。