此为大牛写好后,我转载过来的,内容包括多位大牛对java中程序执行顺序的思考!
- * 几大原则
- * 一、静态成员变量(Static)
- * 1、静态成员变量为类变量,所有对象共享同一内存空间
- * 2、静态成员变量的声明和定义仅在首次加载类时执行一次
- * 3、首次加载类时首先对所有静态成员变量根据类型默认赋初值,然后再对有右值的附右值
- * 二、静态初始块
- * 1、静态初始化块仅在首次加载类时执行一次
- * ······多个静态成员变量与静态始化快参照出现顺序先后执行······
- * 三、动态成员变量
- * 1、动态成员变量定义在每次实例化对象时在构造函数之前执行
- * 四、动态初始化块
- * 1、动态初始化块在每次实例化对象时在构造函数之前执行
- * ······多个动态成员变量与动态初始化块参照出现顺序先后执行······
- * 总结:总的来说,在不涉及继承的前提下,当首次加载类时,按照如下顺序执行
- * 1、按照出现顺序先后执行静态成员变量定义与静态初始化块
- * 2、按照出现顺序先后执行动态成员变量定义与动态初始化块
- * 3、执行构造函数
- * 再次实例化对象时只执行第2、3步即可
- *
- * ············成员变量与定义与初始化块先于构造函数执行·········
- * 五、当涉及到继承时,按照如下顺序执行
- * 1、执行父类的静态成员变量定义与静态初始化块,执行子类的静态成员变量定义与静态初始化块
- * 2、执行父类的非静态成员变量定义与动态初始化块,执行父类构造方法
- * 3、执行子类的非静态成员变量定义与动态初始化块,执行子类构造方法
- * 另:父类构造方法中用到的方法如果已被子类重写,那么在构造子类对象时在调用父类构造函数中使用子类重写的方法
一、先执行内部静态对象的构造方法,如果有多个按定义的先后顺序执行;静态对象在构造的时候也是也先执行其内部的静态对象。
二、再调用父类的构造方法(父类还有父类的话,从最开始的基类开始调用),如果没有明显指定调用父类自定义的构造方法,那么编译器会调用默认的父类构造方法super()。但是如果要调用父类自定义的构造方法,要在子类的构造方法中明确指定。
三、按声明顺序将成员引用对象变量初始化。
四、最后调用自身的构造方法。
下面以一个例子来说明代码如下:
- class Animal{
- String name;
- Animal() {
- System.out.println("class Animal");
- }
- Animal(String name){
- this.name = name;
- System.out.println(name + " class Animal");
- printNumber();
- }
- public void printNumber(){
- }
- }
- class Fish extends Animal{
- Fish() {
- System.out.println("class Fish");
- }
- }
- class GoldFish extends Fish {
- GoldFish() {
- System.out.println("class GoldFish");
- }
- }
- class Cat {
- Cat(){
- System.out.println("class cat");
- }
- }
- class Rabbit {
- private static int number;
- private static Cat cat = new Cat();
- public Rabbit() {
- number++;
- System.out.println(number + "class rabbit");
- }
- }
- class Dog extends Animal{
- public int dogNumber;
- private GoldFish goldFish = new GoldFish();
- static Rabbit blackRabbit = new Rabbit();
- static Rabbit whiterabbit = new Rabbit();
- public Dog() {
- super("Tom");
- System.out.println("class Dog");
- dogNumber = 10;
- System.out.println("The dog's number is:" + dogNumber);
- }
- public void printNumber(){
- System.out.println("The dog's number is:" + dogNumber);
- }
- }
- public class TestInheritanceConstructor extends Animal {
- public static void main(String[] args){
- new Dog(); //Test the executive order of constructor
- }
- }
class cat
1class rabbit
2class rabbit
Tom class Animal
The dog's number is:0
class Animal
class Fish
class GoldFish
class Dog
The dog's number is:10
解释:
输出:class cat 是因为Dog类中有静态成员。而静态成员所在的类Rabbit中又有静态成员。所以最先执行它。验证第 一句。
输出:1class rabbit 和 2class rabbit 是执行类Rabbit构造函数。
输出:Tomclass Animal 执行父类的构造函数,因为用super("")。
输出:The dog's number is:0 可以看出子类的dogNumber还是默认值0
输出:class Animal 和 class Fish 和 class GoldFish是构造goldFish引用对象类型。验证第三句。
输出:class Dog 和The dog's number is:10是执行自己的构造函数。
更详细的内容可以参考以下帖子:http://blog.csdn.net/macheng365/article/details/6403050
http://hi.baidu.com/suofang/item/52e31c61f7548a2669105bf8(此贴为精辟的讲解,膜拜了)