- class A {
- private static int i = 2;
- public A() {
- System.out.println("1.A()...");
- fun();
-
- }
-
- public void fun() {
- System.out.println("A fun()...");
- System.out.println(i);
- }
- }
- class B extends A {
- private static int i = 22;// static,若这里加上static,则i打印出来为22,因为i为静态的,比构造方法先加载
-
- public B() {
- i = 222;
- System.out.println("3.B()...");
- }
-
- public void fun() {
- System.out.println("2. B fun()...");
- System.out.println(i);
- }
- }
- public class Test {
- public static void main(String[] args) {
- B b = new B();
- }
- }
- /*
- B b = new B();
- 此时走B的构造函数,但由于其继承自A类,故又走A的构造方法public A(),
- 调用fun(),注意这里是new B(),也就是B的对象,根据多态原则,子类覆盖了
- 父类的方法,走子类方法,故调用了子类的B fun()方法,然后打印i,由于i还没有
- 显示初始化,故默认初始化为0,若在B中i加上static,则为22,因为static变量优先于构造方法。
- ,所以就出现了,奇妙的情景。
- */
复制代码 对象的初始化顺序:
1.首先执行父类静态的内容,父类静态的内容执行完毕后;
2.接着去执行子类的静态的内容,当子类的静态内容执行完毕之后;
3.再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕;
4.接着执行父类的构造方法,父类的构造方法执行完毕之后;
5.它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块,子类的非静态代码块执行完毕;
6.去执行子类的构造方法。
总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,
然后执行子类非静态代码块和构造方法。
注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。
如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。
|