12

Checkstyle说:

Class should define a constructor.

PMD说:

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

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

4

9 回答 9

17

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

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

但这是我的强迫症,可能是不合理的。有一个应用程序程序员的世界,他们的中心焦点是业务,而不是语言,而且他们不是语言专家。很多人使用的生存技巧是保持风格一致,是否绝对必要不是重点。

于 2010-10-26T13:11:15.277 回答
9

与许多“有争议”的决定一样,事实是它真的没有那么重要。写或不写构造函数。对代码质量和可维护性的影响可以忽略不计。如果您正在与其他人一起编码,那么为了保持一致性,请采用相同的风格,否则 - 随心所欲。

于 2010-10-26T13:23:19.700 回答
7

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

于 2010-10-26T13:18:28.847 回答
1

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

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

于 2010-10-26T13:13:36.160 回答
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
    }

}
于 2010-10-26T13:17:20.283 回答
1

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

另一件事是某些类应该具有一致的状态。例如,您有一个 Book 类。创建没有标题的书是没有意义的,所以需要指定一个带字符串参数的构造函数:

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

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

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

您应该记住默认构造函数默认是公共的,因此如果您想要对此进行一些限制,请考虑使用显式构造函数。

此外,如果您的类相当长,您可以考虑声明一个空的默认构造函数以增加可读性。

于 2010-10-26T13:21:34.693 回答
1

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

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

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

现在,当您创建 Cube1 类的对象时,该对象的所有实例变量都将设置为 10。如果您在这里不使用构造函数,您的实例变量(长度、宽度和高度)将具有默认值(在这个案例)。


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

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

请记住:编译器仅在该类不包含任何其他构造函数时为您的类创建默认构造函数。

于 2010-10-26T13:26:23.550 回答
1

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

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

这就是为什么您应该在需要时显式添加默认构造函数。

于 2010-10-26T13:29:00.070 回答
0

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

于 2019-11-21T23:58:49.660 回答