类初始化和实例初始化
1、类初始化过程
(1)一个类要创建实例需要先加载并初始化该类
main()方法所在的类需要先加载和初始化 ---> 此类中main方法中为空 输出也为5 1 10 6
(2)一个子类初始化要先初始化父类
(3)一个类初始化就是执行<clinit>()方法 字节码文件中,<clinit>()方法由静态类变量显示赋值代码和静态代码块组成
变量显示赋值代码和静态代码块从上到下执行
<clinit>()方法只执行一次
2、实例初始化过程
(1)实例初始化就是执行<init>()方法
<init>()方法可能重载有多个,有几个构造器就有几个<init>()方法
(2)<init>()方法的首行是super()或者super(实例列表),即对应父类的<init>()方法 (最先执行)
<init>()方法由 非静态类变量显示赋值代码和非静态代码块、对应构造器代码组成
非静态变量显示赋值代码和非静态代码块从上到下执行,而对应的构造器代码最后执行(顺序执行)
每次创建实例对象,调用对应的构造器,执行的就是 对应的<init>()方法 (最后执行)
举例:
public class Father { private int i = test(); private static int j = method(); static { System.out.println("1"); } Father() { System.out.println("2"); } { System.out.println("3"); } public int test() { System.out.println("4"); return 1; } public static int method() { System.out.println("5"); return 1; } }
public class Son extends Father { private int i = test(); private static int j = method(); static { System.out.println("6"); } Son() { //super(); 写或者不写都存在,在子类的构造器中一定会调用父类的构造器 System.out.println("7"); } { System.out.println("8"); } public int test() { System.out.println("9"); return 1; } public static int method() { System.out.println("10"); return 1; } public static void main(String[] args) { Son s1 = new Son(); System.out.println(); Son s2 = new Son(); } }
执行顺序:
1、先初始化父类 :
<clinit>()方法
(1)j = method()
(2)静态代码块
父类的静态类变量显示赋值代码和静态代码块 --> 5 1
2、再初始化子类 :
<clinit>()方法
(1)j = method()
(2)静态代码块
子类的静态类变量显示赋值代码和静态代码块 --> 10 6
3、子类的实例化方法
(1)super() 父类的实例初始化 --> 9 3 2
(2)i=test() --> 9
(3)子类的非静态代码块 --> 8
(4)子类的无参构造 -->7
创建了两个Son()对象 因此子类的实例化方法执行两遍 --> 9 3 2 9 8 7
子类的执行结果为:
5 1 10 6 9 3 2 9 8 7 9 3 2 9 8 7
父类的初始化
(1)j = method()
(2)静态代码块
父类的实例初始化
(1)super()
(2)i=test()
(3)子类的非静态代码块
(4)子类的无参构造
注意:非静态方法前面其实一直有一个默认的对象this
this在构造器或者<init>()方法中,他表示正在创建的对象,因此i=test()执行的是子类重写的代码(面向对象多态)
这里的i=test()执行的是子类重写的test()方法
3、方法的重写
(1)、哪些方法不可以被重写
final方法、静态方法、private等子类中不可见的方法
(2)、对象的多态性
子类如果重写了父类的方法,通过子类对象调用的一定是子类重写过的代码
非静态方法默认的调用对象是this
this对象在构造器或者<init>()方法中就是正在创建的对象
4、overload和override的区别
名词 |
Overload方法的重载 |
Override方法的重写 |
位置 |
同一个类中 |
在父子类中 |
方法名 |
必须相同 |
必须相同 |
形参列表 |
必须不同 |
必须相同 |
返回值类型 |
无关 |
void和基数类型:一致;引用类型<= |
抛出的异常列表 |
无关 |
<= |
权限修饰符 |
无关(建议一致) |
>= |