子类构造函数 - 为什么子类构造函数必须存在默认构造函数?

Zak*_*Zak 3 java constructor subclass

给出一个随机类:

public class A<T> {
    public T t;

    public A () {}  // <-- why is this constructor necessary for B?
    public A (T t) {
        this.setT(t);
    }
    public T getT () {
        return this.t;
    }
    protected void setT (T t) {
        this.t = t;
        return;
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一个扩展课程:

public class B extends A<Integer> {
    public B (Integer i) {
        this.setT(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么B要求A有空构造函数?我原以为它会想要使用类似的构造函数而不是默认的构造函数.我尝试编译没有默认的构造函数,但没有它我得到以下消息...

java.lang.NoSuchMethodError: A: method <init>()V not found at B.<init>
Run Code Online (Sandbox Code Playgroud)

谁能解释为什么会这样?

Tho*_*sen 10

重要的是要理解任何构造函数的第一行是调用超级构造函数.super()如果您不自己调用超级构造函数,编译器会通过插入内容来缩短代码.

此外,如果您没有任何构造函数,则会自动插入空的默认构造函数 - 此处A()B()- .

super(...)的B构造函数中没有a ,因此编译器会super()自行插入调用,但您确实有一个带有参数的A构造函数,因此未插入默认的A() - 构造函数,并且手动提供A() - 构造函数,或者调用A(i) - 构造函数.在这种情况下,我建议只是

public class B extends A<Integer> {
    public B (Integer i) {
        super(i);
    }
}
Run Code Online (Sandbox Code Playgroud)


Mac*_*tle 6

您可以使用自己的构造函数A,但必须从B的构造函数中显式调用它,例如:

public B(Integer i) {
  super(i);
  ...
}
Run Code Online (Sandbox Code Playgroud)

如果不这样做,编译器将尝试A通过调用其默认构造函数来实例化自身.