构造器的作用:确保成员变量得到初始化,在new实例之后,可以直接使用

1>构造器初始化顺序:变量定义的顺序决定了初始化的顺序,他们都会在任何方法(包括构造器)调用之前得到初始化(注意,采用类的形式直接去调用静态方法,此时,普通的成员变量将不会被初始化,因为没有为对象在堆中开辟空间,即只调用类的静态方法时,只会对类的静态变量优先进行初始化,然后执行被调用的静态方法,普通变量并不会进行初始化)

  1. class Display{
  2. Display(int market){
  3. System.out.println("Display"+"("+market+")");
  4. }
  5. }
  6. public class Computer {
  7. Display d1 = new Display(1);
  8. static Display d2 = new Display(2);
  9. static void p(){
  10. System.out.println("Computer static method");
  11. }
  12. Display d3 = new Display(3);
  13. Computer(){
  14. System.out.println("Computer"+"()");
  15. }
  16. public static void main(String[] args) {
  17. //Computer.p(); //注意输出结果的不同
  18. new Computer();
  19. }
  20. }

2>静态数据的初始化:无论你创建多少个对象,静态数据都将在类加载到虚拟机的时候,仅仅执行一次。

  1. class Display{
  2. Display(int market){
  3. System.out.println("Display"+"("+market+")");
  4. }
  5. }
  6. public class Computer {
  7. Display d1 = new Display(1);
  8. Computer(){
  9. System.out.println("Computer"+"()");
  10. }
  11. public static void main(String[] args) {
  12. new Computer();
  13. new Conputer();//只打印一个输出语句
  14. }
  15. }

3>将类加载到虚拟机的时候,一个类中如果有静态域和静态代码块,将会执行这些代码(静态方法可以在静态代码块中得到调用)示例如下:

  1. package com.thinking.in.java.course;
  2. class Display{
  3. Display(int market){
  4. System.out.println("Display"+"("+market+")");
  5. }
  6. }
  7. public class Computer {
  8. Display d1 = new Display(1);
  9. static Display d2 = new Display(2);
  10. static void p(){
  11. System.out.println("Computer static method");
  12. }
  13. static {
  14. p();
  15. }
  16. Display d3 = new Display(3);
  17. Computer(){
  18. System.out.println("Computer"+"()");
  19. }
  20. void f(){}
  21. public static void main(String[] args) throws ClassNotFoundException {
  22. //将类加载到虚拟机中
  23. Class.forName("com.thinking.in.java.course.Computer");
  24. //Computer.p();
  25. //new Computer();
  26. }
  27. }

4>类加载的过程

  1. 1,编译Java文件,便于定位出class完整的路径信息
  2. 2,将class文件载入虚拟机中,执行有关静态初始化的所有动作;
  3. 且只执行一次,按照定义的顺序,静态代码块并无优先权限,静态代码块中可以调用静态方法
  4. 3,执行new操作,在堆中为对象分配足够的空间
  5. 4,初始化该空间,其中基本类型为默认值,引用类型为null
  6. 5,按照变量的定义顺序,执行初始化动作;和普通代码块并无关系;
  7. 6,执行构造器方法

image.png

class Bowl{
    Bowl(int marker){
        System.out.println("Bowl(" + marker+")");
    }
    void f1(int marker){
        System.out.println("f1(" + marker + ")");
    }
}
class Table{
    static Bowl bowl1 = new Bowl(1);
    Table(){
        System.out.println("Table()");
        bowl2.f1(1);
    }
    void f2(int marker){
        System.out.println("f2(" + marker + ")");
    }
    static Bowl bowl2 = new Bowl(2);
}
class Cupboard{
    Bowl bowl3 = new Bowl(3);
    static Bowl bowl4 = new Bowl(4);
    Cupboard(){
        System.out.println("Cupboard()");
        bowl4.f1(2);
    }
    void f3(int marker){
        System.out.println("f3(" + marker + ")");
    }
    static Bowl bowl5 = new Bowl(5);
}
public class StaticIninialization{
    public static void main(String[] args){
        new Cupboard();
        System.out.println("==========");
        new Cupboard();
        System.out.println("==========");
        table.f2(1);
        cupboard.f3(1);
    }
    static Table table = new Table();
    static Cupboard cupboard = new Cupboard();
}

/*output:
  Bowl(1)
  Bowl(2)
  Table()
  f1(1)
  Bowl(4)
  Bowl(5)
  Bowl(3)
  Cupboard()
  f1(2)
  Bowl(3)
  Cupboard()
  f1(2)
  ==========
  Bowl(3)
  Cupboard()
  f1(2)
  ==========
  f2(1)
  f3(1)  
*/