Java 实例的构造 和 Initialization block

  方法很多, 直接上代码:

public class Zoo {
    public static void main(String[] args) {
        
        
        // 调用构造函数
        Rabbit r1 = new Rabbit();

        // 相当于一个临时的构造函数
        Rabbit r2 = new Rabbit() {{
            weight = 10;
            maxHealth = 20;
            health = 10;
            speed = 2;
            year = 10;
        }};

    }
}    

 

  类的static初始化和实例初始化:

class Rabbit extends Animal{
    
    
    static final double basicSpeed = 3.0;
    static int RabbitNum;
    
    

    //  1. 类第一次被使用时执行
    static {
        System.out.println("Rabbit static initializaion.");
        RabbitNum = 0;
        
    }
    
    
    // 3. 每个兔子都有field a,在Rabbit的构造函数总调用
    int a;
    {
        System.out.print("Miao~");
    }
    
    // 2. Rabbit先调用super()
    Rabbit(){
        
        super(5, 10, 10, 0, basicSpeed);
 
                // 4. 打印语句
        System.out.println("Rabbit!");
    }
}        

   来个复杂一点的例子,假设上面的Rabbit类加了一个 String name = "", 我们发现一个Rabbit对象的构造过程分为下面的过程:

  1.   static { ... }  // 静态初始化,当类被加载进入jvm时执行,仅执行一次
  2.   进入Rabbit的构造方法
  3.   递归调用super()
  4.   属于其他类的field 初始化, 如 String name = “”
  5.        执行实例初始化语句块, 如 int a;  { .... }
  6.        构造方法中剩下的语句

  我们再对上面的例子进行修改, 给Rabbit类添加一个 { ...}语句块,并将它与上文的 int a ; { .. }, String name = "" , 打乱顺序重新安排在Rabbit的各处,

Debug发现,它们的执行顺序是从上到下,也就是先出现的语句先被执行。

  综上, 我们做出总结:一个类对象的构造过程调用的函数和执行的语句(块)的顺讯如下:

  

  1. 父类的静态初始化块 (先进入子类的构造函数, 递归调用super)
  2. 子类的静态初始化块
  3. 父类的初始化块 (由上到下执行)
  4. 父类的构造函数(完成)
  5. 子类的初始化块
  6. 子类的构造函数(完成)

猜你喜欢

转载自www.cnblogs.com/Tsuko/p/9947683.html