一道关于static的有趣题目

现有3个类

public class A {
    public static int b = B.a;
    public static A plus = new A("A");
    public static final int finalInt = (int) (Math.random() * 100);
    public static B p = new B("A");

    public static final String finalStr = "finalStr";
    public static final Integer finalInteger = new Integer(10);
    public static int a = 1;
    public static B c = null;

    public A(String from) {
        System.out.println("----------- begin A::A ----------------");
        System.out.println("A::A, from=" + from);
        System.out.println("A::A, A.b=" + A.b);
        System.out.println("A::A, A.finalInt=" + A.finalInt);
        System.out.println("A::A, A.finalInteger=" + A.finalInteger);
        System.out.println("A::A, B.a=" + B.a);
        System.out.println("A::A, B.plus=" + B.plus);
        System.out.println("----------- end A::A ----------------");
    }
}

class B {
    public static int t = A.a;
    public static A plus = new A("B");
    public static int a = 1;

    public B(String from) {
        System.out.println("----------- begin B::B ----------------");
        System.out.println("B::B, from=" + from);
        System.out.println("B::B, B.a=" + B.a);
        System.out.println("B::B, A.a=" + A.a);
        System.out.println("B::B, A.p=" + A.p);
        System.out.println("B::B, A.plus=" + A.plus);
        System.out.println("B::B, A.finalInt=" + A.finalInt);
        System.out.println("B::B, A.finalInteger=" + A.finalInteger);
        System.out.println("B::B, A.finalStr=" + A.finalStr);
        System.out.println("----------- end B::B ----------------");
    }
}

class C {
    public static final A a = new A("C");
}

问,当运行以下代码时,输出什么

public static void main(String[] arg) {
    System.out.println("main, A.b=" + A.b);
    System.out.println("main, B.t=" + B.t);
    System.out.println("main, C.a=" + C.a);
}

本题主要知识点有以下几点:

1.只有主动请求一个类时,这个类才会初始化,仅包含静态变量和静态函数(static的),比如"A.b=" + A.b时,请求了A,所以会初始化A ,但是,初始化A并不会调用A中的构造函数,只有当new A时,才会调用构造函数;
2.继承关系时,先初始化父类,再初始化子类;
3.静态变量会按照声明的顺序依次声明,并设置为该类型的默认值,但不赋值为初始化的值,比如A.plus会先声明并设置为null,之后再按顺序初始化;
4.声明完毕后,再依次设置为初始化的值,没有初始值的就跳过;
5.当初始化A.b=B.a时,暂停初始化A,设置当前类为B,并执行步骤3,比如执行A.b=B.a时,不继续执行A.plus = new A("A"),而是设置当前类为B,然后依次声明B.t , B.plus , B.a;
6.当请求一个已暂停的类时,该类不会继续初始化,而是将所请求变量的当前值返回,例如执行A.b=B.a时,A暂停初始化,当初始化B过程中,调用B.t=A.a时,不会去继续初始化A,而是将A.a当前值0赋值给B.t;
7.当初始化B.plus = new A("B")时,暂停初始化B.plus,实例化A("B")(就是直接调用A的构造函数,先不继续初始化其他参数),并赋值给B.plus,例如,A.b = B.a时跳到了B,执行B的初始化,初始化到b.plus = new A("B")时,会停止初始化B.plus,并执行A的构造函数 public A(string from);
8.当A的构造函数里需要获得B.a的值时,如果B.a正在初始化并处于暂停状态,直接取B.a的当前值,不再等待B.a初始化,例如,B.plus = new A("B")会停止初始化B并执行A的构造函数,在构造函数中调用了B.a,这时不会再跳到B,而是直接取B.a的当前值0;
9.final、静态常量其实是遵循普遍静态变量的初始化规则的,但是在编译时,编译器会将不可变的常量值在编译的地方替换掉,例如,编译器会将"finalStr"赋值给finalStr,因为"finalStr"本身是final的 ,但是不会将10赋值给finalInteger,因为还没有请求new Integer(10)。

 

本题最终结果:

----------- begin A::A ----------------
A::A, from=B
A::A, A.b=0
A::A, A.finalInt=0
A::A, A.finalInteger=null
A::A, B.a=0
A::A, B.plus=null
----------- end A::A ----------------
----------- begin A::A ----------------
A::A, from=A
A::A, A.b=1
A::A, A.finalInt=0
A::A, A.finalInteger=null
A::A, B.a=1
A::A, B.plus=com.happydog.exam.about_constructor.A@4439f31e
----------- end A::A ----------------
----------- begin B::B ----------------
B::B, from=A
B::B, B.a=1
B::B, A.a=0
B::B, A.p=null
B::B, A.plus=com.happydog.exam.about_constructor.A@5d5eef3d
B::B, A.finalInt=43
B::B, A.finalInteger=null
B::B, A.finalStr=finalStr
----------- end B::B ----------------
main, A.b=1
main, B.t=0
----------- begin A::A ----------------
A::A, from=C
A::A, A.b=1
A::A, A.finalInt=43
A::A, A.finalInteger=10
A::A, B.a=1
A::A, B.plus=com.happydog.exam.about_constructor.A@4439f31e
----------- end A::A ----------------
main, C.a=com.happydog.exam.about_constructor.A@6cc4c815

 

转载于:https://my.oschina.net/u/3758884/blog/1608193

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值