Java子类构造函数不调用父类构造函数

标签 java inheritance constructor

前几天我遇到了一个奇怪的情况。这是:

我有一个抽象类和一个扩展它的子类。抽象类有一个无参数构造函数来初始化映射,但仅此而已。

子类没有我显式编写的任何构造函数,并且一切正常。

然后有一天,我在子类中添加了一个自定义构造函数,其中包含一堆用于单元测试的参数。然而,这破坏了我的主程序,因为其父类中的映射始终为空。

为了解决这个问题,我在子类中放置了另一个完全空白的构造函数(没有参数或任何东西)。由于某种原因,这确保了父类(super class)构造函数将被调用并且不会抛出空指针异常。为什么以前没有被调用,为什么现在可以工作?

子类:

public class BillToSite extends XWStoreRequestDataElement {
private String country;
private String state;
private String county;
private String city;
private String zip;
private String address;

public BillToSite() { } //WHY DOES THIS FIX IT???

//Only used for unit test. 
public BillToSite(String address, String city, String state, String zip, String county, String country){
    this.address = address;
    this.city = city;
    this.state = state;
    this.zip = zip;
    this.county = county;
    this.country = country;
}

抽象类:

public abstract class XWStoreRequestDataElement {
private Map<String, String> attributes;

public XWStoreRequestDataElement(){
    attributes = new HashMap<>();
}

最佳答案

我无法解释为什么您会遇到带有 attributes=nullBillToSite 实例。这与 Java 的工作方式相矛盾。但我可以解释为什么你必须编写无参数构造函数。

显式无参数构造函数的必要性

我认为在您的程序中 BillToSite 实例是使用 new BillToSite() 创建的,无论是显式的还是通过某个框架...(否则该类不会有任何情况)。

在原始的 BillToSite.java 中,您没有显式构造函数,因此 Java 编译器为您创建了一个与您询问的构造函数实际上相同的构造函数。

引入 6-args 构造函数会停用编译器自动创建无参数构造函数的功能,并且由于您的代码依赖于此构造函数,所以我很清楚它无法再工作。通常,您应该在 new BillToSite() 调用中遇到编译错误。如果您没有得到它们,我猜实例创建是使用反射发生在某个隐藏的地方。

因此,当您编写显式无参数构造函数时,您重新引入了不再自动生成的缺失元素。

调用 super 构造函数

你永远不需要用 super() 显式地开始一个构造函数(如果你省略它,我们可能会认为它是不好的风格,因此不清楚要使用哪个父类(super class)构造函数)。如果您没有显式调用 super(...)this(...) 构造函数,编译器会有效地插入 super() > 从一开始。在这方面,其他一些答案具有误导性。

因此,将该行添加到 BillToSite(...) 构造函数中不会改变任何内容。

我建议您在调试器控制下运行程序,并在 BillToSite() 构造函数上设置断点,并观察 attributes 字段。我确信它将被初始化为一个空的HashSet。如果您稍后遇到空值,则问题一定出在代码的另一部分。

关于Java子类构造函数不调用父类构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46307275/

相关文章:

具有范围限制的 Java 类构造函数参数

javascript - 如何使用 javascript 创建有效的 svg 元素

java - Java 中不允许有异常的函数

java - 使用递归添加分数

c# - 如何获取FxCop中callvirt IL指令实际调用的方法

Java:可以访问父类(super class)字段和方法的策略模式?

c++ - 在 C++ 中使用初始化列表时的奇怪行为

java - JSTL 在 ul - li html 标记中打印数组列表值。正确的算法。

java - 具有多个具有相同自定义数据类型的成员的实体

c# - 调用基函数然后继承函数