8

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

public ClassName() {
    super();
}

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

编辑:

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

此外,这不是一个技巧问题。写这篇文章的人比我年长,所以我想确保在我和他谈论这件事之前,我已经涵盖了所有的可能性。

4

6 回答 6

14

如果您的代码中有一个非默认构造函数,那么编译器将不会提供默认的无参数构造函数。因此,如果有人尝试使用new YourClass(). 这将导致编译错误。

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

于 2013-09-10T17:03:00.973 回答
3

其他答案已经很好了,但为了后代/乐趣,值得注意的是:

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

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

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

}
于 2013-09-10T17:43:57.107 回答
1

这样做可能是有原因的,例如,如果您有非默认构造函数,但由于某种原因仍需要默认构造函数可见(Hibernate 等 API 需要默认构造函数可见)。

请记住,如果您有一个非默认构造函数并且没有实现默认构造函数,那么默认构造函数将根本不存在,无论是在类内部还是外部。

于 2013-09-10T17:03:07.543 回答
1

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

例如,您有这样的课程:

class A {
    private int a;

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

你想在某处使用它:

A a = new A(1);

没关系,但是如果您尝试使用非参数化构造函数:

A a = new A();

会有一个错误,您必须将默认构造函数添加到类 A

于 2013-09-10T17:07:21.187 回答
1

这没有很好的技术原因。不是每个人都费心去学习关于默认构造函数的规则,很多人只是喜欢按照他们一贯的方式做事。我不喜欢在代码库中有这样无用的东西。但是,由于它不会造成任何损坏,因此删除它也不是一个高优先级,因此除非需要进行大规模返工,否则我将不理会它。

在您必须与他人共享代码的工作场所中保持理智的关键是接受您的工作人员会以与您不同的方式做事。考虑将他人代码的更改限制在重要的事情上。如果向他们询问他们盲目的习惯或强迫症的特质并没有成效,请不要感到惊讶。

于 2013-09-10T17:38:42.507 回答
0

我显式地编写了一个等效于默认构造函数的无参数构造函数,因此我可以提供有关无参数构造函数的注释。我发现这很有用,因为我是按合同风格编写的。

例如:

 /**
  * <p>
  * Construct an {@linkplain #isEmpty() empty} service directory.
  * </p>
  */
 public ServiceDirectory() {
    // Do nothing
 }
于 2013-09-16T11:53:32.120 回答