为什么有人会故意实现默认构造函数的默认实现?

时间:2013-09-10 17:01:24

标签: java

刚刚从同事的代码中删除了以下代码:

public ClassName() {
    super();
}

我只是想确保我做对了。为什么有人故意写这个?这正是编译器默认插入的不是吗?

编辑:

澄清:那是唯一的构造函数。

此外,这不是一个棘手的问题。写这篇文章的人比我高,所以我想确保在谈到这个问题之前我已经涵盖了所有可能性。

6 个答案:

答案 0 :(得分:14)

如果代码中有非默认构造函数,则编译器将不提供默认的无参数构造函数。因此,如果有人尝试使用new YourClass()创建对象。这将导致编译错误。

因此,如果存在其他构造函数,则需要确保代码中没有对该类默认构造函数的引用。

答案 1 :(得分:3)

其他答案已经很好,但对于后人/乐趣,值得注意的是:

  • super()来电总是多余的
  • 如果没有其他构造函数,无论是否提供public,no-arg,super() - 构造函数,生成的字节码都完全相同

为了演示,这里有四个类:

public class Base {}

public class SubA extends Base {
  // nothing
}

public class SubB extends Base {
  public SubB() {
    // nothing in ctor
  }
}

public class SubC extends Base {
  public SubC() {
    super();
  }
}

如果在三个子类中的每一个上运行javap -c,您将看到它们生成的字节码完全相同(当然除了它们的类名):

$ javap -c SubA SubB SubC
Compiled from "SubA.java"
public class SubA extends Base{
public SubA();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method Base."<init>":()V
   4:   return

}

Compiled from "SubB.java"
public class SubB extends Base{
public SubB();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method Base."<init>":()V
   4:   return

}

Compiled from "SubC.java"
public class SubC extends Base{
public SubC();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method Base."<init>":()V
   4:   return

}

答案 2 :(得分:1)

可能有理由这样做,例如,如果你有非默认构造函数但仍然需要默认构造函数由于某种原因可见(像Hibernate这样的API需要对默认构造函数的可见性)。

请记住,如果您有一个非默认构造函数并且实现默认构造函数,那么默认构造函数将根本不存在,既不在内部也不存在班级或外部。

答案 3 :(得分:1)

当在同一个类中有参数化构造函数但你想调用默认构造函数时,你实现这样的构造函数,因为在这种情况下,将不提供默认构造函数。

例如,你有这样的课程:

class A {
    private int a;

    public A(int a) {
        this.a = a;
    }
}

你想在某个地方使用它:

A a = new A(1);

没关系,但如果你想尝试使用非参数化的构造函数:

A a = new A();

会出现错误,您必须将默认构造函数添加到A类

答案 4 :(得分:1)

这没有很好的技术原因。并不是每个人都很难学习关于默认构造函数的规则,而且许多人只是喜欢按照他们一直以来的方式做事。我不喜欢在代码库中有这样无用的东西。但是,由于它没有造成任何损害,因此将其删除也不是一个高优先级,所以除非需要批量返工,否则我不能单独处理。

在您必须与他人分享代码的工作场所保持理智的关键是接受您的cow-orkers将以不同的方式做事。考虑限制对他人的改变&#39;代码重要的事情。如果向他们询问他们的无意识习惯或强迫性特质,那就不会感到惊讶。

答案 5 :(得分:0)

我明确地编写了一个与默认构造函数等效的无参数构造函数,因此我可以提供有关无参数构造函数的注释。我觉得这很有用,因为我用契约样式编写编程。

例如:

 /**
  * <p>
  * Construct an {@linkplain #isEmpty() empty} service directory.
  * </p>
  */
 public ServiceDirectory() {
    // Do nothing
 }