类初始化和实例初始化

Table of Contents

一、类的初始化时机

二、类初始化过程

三、实例初始化

四、方法重写override

五、静态结构和非静态结构


一、类的初始化时机

在《深入理解java虚拟机》这本书里面讲到了类的六个初始化时机

  1. 创建类的实例
  2. 访问类的静态变量(注意:当访问类的静态并且final修饰的变量时,不会触发类的初始化。),或者为静态变量赋值。
  3. 调用类的静态方法(注意:调用静态且final的成员方法时,会触发类的初始化!一定要和静态且final修饰的变量区分开!!)
  4. 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。如:Class.forName("********");注意通过类名.class得到Class文件对象并不会触发类的加载。
  5. 初始化某个类的子类
  6. 直接使用java.exe命令来运行某个主类(java.exe运行,本质上就是调用main方法,所以必须要有main方法才行)。

 

二、类初始化过程

1 一个类要创建实例需要先加载并初始化该类

  •    main方法所在的类需要优先加载和初始化

2 一个子类要初始化需要先初始化父类

3 一个类初始化就是执行clinit()方法

  • clinit方法由静态类变量显示赋值代码和静态代码块组成,声明不属于,只有显示赋值才算。
  • 类变量显示赋值代码和静态代码块从上到下顺序执行
  • clinit方法只执行一次

 

三、实例初始化

1 实例初始化执行的事init方法

  • init方法可能重载有多个,有几个构造器就有几个init方法
  • init由非静态实例变量显示赋值代码和非静态代码块,对应构造器代码组成。
  • 非静态实例变量显示赋值和非静态代码块按照顺序执行,构造器最后执行。
  • 每次创建实例对象,调用对应的构造器,执行的就是对应init方法
  • init方法首行是super()或者super(实例形参),即对应的父类的init方法

 

类初始化:先父类的初始化,后子类的初始化

 

实例初始化:每个init方法首行是super()或者super(实例形参),即对应的父类的init方法

父类的实例初始化:super(),父类非静态实例变量显示赋值,父类的非静态代码块,父类构造器

子类的实例初始化:super() ,子类非静态实例变量显示赋值,子类的非静态代码块,子类构造器。 

 

四、方法重写override

1 哪些方法不可以被重写

  • final方法
  • 静态方法
  • private等子类不可见的方法

2 对象的多态性

  • 子类如果重写了父类的方法,通过子类对象调用的一定是子类重写过的代码
  • 非静态方法默认调用对象是this
  • this对象在构造器或者说init()方法中就是正在创建的对象

五、静态结构和非静态结构


静态结构随着类加载初始化:所以
静态结构中不能调用非静态结构
非静态结构可以调用静态机构

 

你可能感兴趣的:(Java)