给出一个随机类:
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;
}
}
扩展课程:
public class B extends A<Integer> {
public B (Integer i) {
this.setT(i);
}
}
为什么B要求A拥有空构造函数?我原以为它会想要使用类似的构造函数而不是默认的构造函数。我尝试在没有默认构造函数的情况下进行编译,但是没有它我得到以下消息......
java.lang.NoSuchMethodError: A: method <init>()V not found at B.<init>
任何人都可以解释为什么会这样吗?
答案 0 :(得分:10)
重要的是要理解任何构造函数的第一行是调用超级构造函数。如果您没有自己调用超级构造函数,编译器会在封面下插入super()
来缩短代码。
此外,如果您没有任何构造函数,则会自动插入一个空的默认构造函数 - 此处为A()
或B()
。
您的B构造函数中没有super(...)
,因此编译器会自行插入super()
调用,但您做有A - 带有参数的构造函数,因此未插入默认的A() - 构造函数,您必须手动提供A() - 构造函数,或者调用A(i) - 构造函数。在这种情况下,我建议只有
public class B extends A<Integer> {
public B (Integer i) {
super(i);
}
}
答案 1 :(得分:6)
您可以在A
中使用自己的构造函数,但必须从B的构造函数中明确地调用它,例如:
public B(Integer i) {
super(i);
...
}
如果不这样做,编译器将尝试通过调用其默认构造函数来实例化A
本身。
答案 2 :(得分:2)
如果你没有使用super(i)
作为构造函数的第一行调用超级构造函数,它将隐式调用默认的超级构造函数