一、类加载过程
在Java中,类是动态加载的。当第一次使用这个类的时候才会加载,加载一个类,会查看其父类是否已加载,如果没有,则会先加载其父类。
一个类的信息:
1)类变量、类方法、实例变量、实例方法
2)类初始化代码 (1、定义静态变量时的赋值语句 2、静态初始化代码块)
3)实例初始化代码(1、定义实例变量时的赋值语句 2、实例初始化代码块)
4)父类信息引用
类加载过程:
1)分配内存保存类的信息(方法区)
2)给类变量赋默认值
3)加载父类
4)设置父子关系
5)执行类初始化代码
类加载顺序:
普通类:
1)类变量(默认值)
2)static{ }静态代码块
3)构造代码块
4)构造方法
父类&子类(当子类加载时):
1)父类类变量(默认值),在加载子类类变量(默认值)
2)父类中的static { }静态代码块,在执行子类中的static { }静态代码块 (父、子类中类变量可以被此步骤赋值)
3)父类中的构造代码块,在执行父类中的构造方法
4)子类中的构造代码块,在执行子类中的构造方法
5)在new 第二个对象时,不会在执行1)和2)了,从3)执行
例子:父类
public class MyObj {
public MyObj(){ System.out.println("A"); }
{ System.out.println("B"); }
{ System.out.println("C"); }
static { System.out.println("D"); }
static { System.out.println("E"); }
}
子类
public class MySon extends MyObj {
public MySon(){ System.out.println("1"); }
{ System.out.println("2"); }
{ System.out.println("3"); }
static { System.out.println("4"); }
static { System.out.println("5"); }
}
new MySon() 输出 DE45 BCA 231
二、对象创建过程
创建对象过程(前提:进行了类加载):
1)分配内存(堆)
2)对所有实例变量赋默认值
3)执行实例初始化代码(先父类构造方法,在子类构造代码块,在子类构造方法)
注:
在堆上定义的对象,除了保存类的实例变量外,还保存着实际类信息的引用。
子类new对象时:无参子类构造方法:先调用父类无参构造方法
有参子类构造方法:先调用父类有参构造方法
调用父类构造方法时,若其中调用了子类重写的方法,先优先使用子类的方法