函数初始化

先看代码

class Parent {
    int i = 1;
    Parent() {
        System.out.println(i);
        int x = getValue();
        System.out.println(x);
    }
    {
        i = 2;
    }//这个叫构造块
    protected int getValue() {
        return i;
    }
}

class Son extends Parent {
    int j = 1;
    Son() {j = 2;}
    protected int getValue() {return j;}
}
class Test {
    public static void main(String[] args) {
        Son son = new Son();
        System.out.println(son.getValue());
    }
}

我本来以为上述代码输出是1,1,2。
原因是:new son时,会先初始化parent,parent最开始将i赋值1,然后执行构造函数,输出1;然后继续往下走,getvalue得到1并输出1,最后将i赋值2。然后son.getValue()的时候,j=2这个先会在构造函数执行。所以最后输出2.

但是真实情况是:对parent进行初始化时,先执行 构造块,将i赋值2,然后输出2;接着调用getvalue的时候,调用的是son的getvalue,此时j没有初始化,j=0。最后调用son.getValue()的时候,son已经被初始化了,输出2.。所以正常的结果是2,0,2.

这里涉及到知识盲区就是说:如果子类覆盖了父类的方法,则在构造函数中, 调用的方法也是子类的 。

另外还有一段代码

// 程序B
public class MagimaTest {
    public static void main(String[] args) {
        magimaFunction();
    }
    static MagimaTest st = new MagimaTest();
    static {
        System.out.println("1");
    }
    {
        System.out.println("2");
    }
    MagimaTest() {
        System.out.println("3");
        System.out.println("a=" + a + ",b=" + b);
    }
    public static void magimaFunction() {
        System.out.println("4");
    }
    int a = 110;
    static int b = 112;
}

我本来以为输出是:
1
4
3
a=0,b=112

但是实际上是:
2
3
a=110,b=0
1
4

在执行main之前,需要初始化MagimaTest类。
先执行static MagimaTest st = new MagimaTest();
然后执行构造函数,但是在开始之前先执行构造函数。此时输出2.
初始化a
然后执行构造函数,此时a=110,b未初始化。输出3; a=110,b=0.
然后st成员变量初始化结束,执行下一个static。输出1.
继续初始化下一个static 变量b
最后调用magimaFunction 输出4.

在进行static MagimaTest st = new MagimaTest();时,下面的static不进行初始化,需要先将MagimaTest的构造步骤完成。因此a会在b前面进行赋值。

猜你喜欢

转载自blog.csdn.net/huqianlei/article/details/91488254