在之前一篇文章里 我提到了类中变量对象初始化的两种方式
class A1 {
B b = new B();
A1() {
}
}
//and
class A2 {
B b;
A2() {
b = new B();
}
}
当时的结论是 除了代码风格的不同以外,他们没有区别。 但是对于继承了A1和A2 并重载了构造函数的类会怎样呢?
如下程序:
package tset.babybear;
public class DiffInConstructor {
public static void main(String[] args) {
C1 c1 = new C1();
C2 c2 = new C2();
System.out.println(c1.b.toString());
System.out.println(c2.b.toString());
}
static class A1 {
B b = new B(1);
A1() {
System.out.println("A1 is constructed");
}
}
static class A2 {
B b;
A2() {
b = new B(2);
System.out.println("A2 is constructed");
}
}
static class B {
B(int i) {
System.out.println("B" + i + " is constructed");
}
}
static class C1 extends A1 {
C1() {
}
}
static class C2 extends A2 {
C2() {
}
}
}
运行结果如下:
B1 is constructed
A1 is constructed
B2 is constructed
A2 is constructed
tset.babybear.DiffInConstructor$B@5e1077
tset.babybear.DiffInConstructor$B@18b3364
无论那个, B类的对象都被正确的初始化了 也就是说 还是没有任何区别
研究了下 发现是这样的
子类的构造方法上如果没有明确的调用父类的构造方法 为了类中的成员对象能够正确的初始化 编译器会自动的添加上父类的默认构造方法(不带参数的构造方法) 如果父类定义了带参数的构造方法 但是没有定义默认构造方法 编译器不会为其创建默认构造方法 这样在编写程序的时候 如果子类没有定义构造方法 或者构造方法中没有显式的调用父类的构造方法编译器会报错: Implicit super constructor *** is undefined. Must explicitly invoke another constructor
评论!