标签:
class Meal { public Meal() { System.out.println("Meal()--构造啦!"); } } class Bread { public Bread() { System.out.println("Bread()--构造啦!"); } } class Cheese { public Cheese() { System.out.println("Cheese()--构造啦!"); } } class Lettuce { public Lettuce() { System.out.println("Lettuce()--构造啦!"); } } class Lunch extends Meal { public Lunch() { System.out.println("Lunch()--构造啦!"); } } class PortableLunch extends Lunch { public PortableLunch() { System.out.println("PortableLunch()--构造啦!"); } } public class Sandwich extends PortableLunch { private Bread bread = new Bread(); private Cheese cheese = new Cheese(); private Lettuce lettuce = new Lettuce(); public Sandwich() { System.out.println("Sandwich()--构造啦!"); } public static void main(String[] args) { new Sandwich(); } }
输出结果如下:
Meal()--构造啦!
Lunch()--构造啦!
PortableLunch()--构造啦!
Bread()--构造啦!
Cheese()--构造啦!
Lettuce()--构造啦!
Sandwich()--构造啦!
再看一例:
class Insect { private int i = 9; protected int j; public Insect() { System.out.println("i=" + i + " j=" + j); j = 39; } private static int x1 = printInit("static Insect x1"); protected static int printInit(String s) { System.out.println(s); return 47; } } class Beetle extends Insect { private int k = printInit("Beetle k "); public Beetle() { System.out.println("k=" + k + " j=" + j);//这个j是父类的 j = 25; } private static int x2 = printInit("static Beetle x2"); public static void main(String[] args) { System.out.println("Beetle constructor"); Beetle beetle = new Beetle();
System.out.println();
System.out.println("Beetle constructor2");
Beetle beetle2 = new Beetle();
} } //输出结果 /* static Insect x1 static Beetle x2 Beetle constructor i=9 j=0 Beetle k i=47 j=39
Beetle constructor2
i=9 j=0
Beetle k
k=47 j=39
*/
在Beetle上运行java时,所发生的第一件事就是试图访问Beetle.main()(一个static方法),于是加载器开始启动并找出Beetle类的编译代码(在名为Beetle.class文件中)。在对它进行加载的过程中,编译器注意到它有一个父类(这是由extends得知),于是它继续加载(父类)。不管你是否打算产生一个该父类的对象,这都要发生(请尝试将对象创建代码注释掉,以便证明这一点)。
如果该父类还有其自身的父类,那么第二个父类就会被加载,如此类推。接下来,根父类中的static初始化(在本例是Insect)即会被执行,然后是下一个子类,以此类推。这种方式很重要,因为子类的static初始化可能会依赖于父类成员能否被正确初始化。
至此为止,必要的类都已经加载完毕,对象才可以创建了。首先,对象中的所有基本类型都会被设为默认值,对象引用被设为null--这是通过将对象内存设为二进制零值而一举产生的。然后,父类的构造器会被调用。在父类构造器完成之后,实例变量按其次序被初始化,最后构造器的其余部分被执行。
标签:
原文地址:http://www.cnblogs.com/linlin-meimei/p/4349897.html