与 与 类的初始化顺序


这两种方法有什么区别呢?

首先:这两个方法一个是虚拟机在装载一个类初始化的时候调用的(clinit)。另一个是在类实例化时调用的(init)

 

首先说说类的初始化:

在Java代码中,一个正确的初始值是通过类变量初始化语句或者静态初始化语句给出的。一个类变量初始化语句是

变量声明后的等号和表达式:

Java代码   收藏代码
  1. class Example {  
  2.        static int size = 3 * (int) (Math.random() * 5.0);  
  3. }  

 

静态初始化语句是一个以static开头的语句块:

Java代码   收藏代码
  1. class Example{  
  2.      static int size;  
  3.      static {  
  4.            size = 3 * (int) (Math.random() * 5.0);  
  5.      }  
  6. }  

 所有的类变量初始化语句和类型的静态初始化语句都被Java编译器收集到了一起,放在一个特殊的方法中。这个方法就是

 

我们在来看看这个方法:

方法是在一个类进行对象实例化时调用的。实例化一个类有四种途径:调用new操作符;调用Class或java.lang.reflect.Constructor对象的newInstance()方法;调用任何现有对象的clone()方法;通过java.io.ObjectInputStream类的getObject()方法反序列化。

 

Java编译器会为它的每一个类都至少生成一个实例初始化方法。在Class文件中,被称为""

 

现在知道了吧, 一个是用于初始化静态的类变量, 一个是初始化实例变量!




Java在编译之后会在字节码文件中生成方法,称之为实例构造器,该实例构造器会将语句块,变量初始化,调用父类的构造器等操作收敛到方法中,收敛顺序(这里只讨论非静态变量和语句块)为: 
1. 父类变量初始化 
2. 父类语句块 
3. 父类构造函数 
4. 子类变量初始化 
5. 子类语句块 
6. 子类构造函数

所谓收敛到方法中的意思就是,将这些操作放入到中去执行

 
Java在编译之后会在字节码文件中生成方法,称之为类构造器,类构造器同实例构造器一样,也会将静态语句块,静态变量初始化,收敛到方法中,收敛顺序为: 
1. 父类静态变量初始化 
2. 父类静态语句块 
3. 子类静态变量初始化 
4. 子类静态语句块

方法是在类加载过程中执行的,而是在对象实例化执行的,所以一定比先执行。所以整个顺序就是: 
1. 父类静态变量初始化 
2. 父类静态语句块 
3. 子类静态变量初始化 
4. 子类静态语句块 
5. 父类变量初始化 
6. 父类语句块 
7. 父类构造函数 
8. 子类变量初始化 
9. 子类语句块 
10. 子类构造函数

初始化顺序

如下父类代码

public class Parent {
    static int a = 1;
    int b = 1;
    static {
        System.out.println("parent static block(a):" + (++a));
    }
    {
        System.out.println("parent  block(b):" + (++b));
    }
    public Parent() {
        System.out.println("parent construction");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

子类代码

public class Child extends Parent {
    static int a = 1;
    int b = 1;
    static {
        System.out.println("child static block(a):" + (++a));
    }
    {
        System.out.println("child  block(b):" + (++b));
    }
    public Child() {
        System.out.println("child construction");
    }
    public static void main(String[] args) {
        new Child();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

最终输出结果为

parent static block(a):2
child static block(a):2
parent  block(b):2
parent construction
child  block(b):2
child construction
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6


你可能感兴趣的:(Java)