Java中类的构造和初始化之二

2013年 6月 14日

tags: java


之前一篇文章里 我提到了类中变量对象初始化的两种方式

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

评论!

社交