阿里的一道静态方法和静态代码块牛逼笔试题

package zhiyinyong;

public class StaticTest {
    
    public static int k=0;  
    public static StaticTest s1=new StaticTest("s1");
   
    public static StaticTest s2=new StaticTest("s2");  
    public static int i=print("i");  
    public static int n=99;  
    public int j=print("j");  
      
    {  
        print("构造块");  
    }  
      
    static  
    {  
        print("静态块");  
    }  
      
    public static int print(String s)  
    {   System.out.println("nihao");
        System.out.println(++k+":"+s+"\ti="+i+"\tn="+n);  
        ++n;
        System.out.println("hahn="+n);
        return ++i;  
    }  
      
    public StaticTest(String s)  
    {   System.out.println("haohao");
        System.out.println(++k+":"+s+"\ti="+i+"\tn="+n);  
        ++i;  
        System.out.println("nimei="+i);
        ++n;  
        System.out.println("gunsn="+n);
    }  
 
    public static void main(String[] args) {  
        new StaticTest("init");  
    }  
}


运行结果:

 

nihao
1:j    i=0    n=0
hahn=1
nihao
2:构造块    i=1    n=1
hahn=2
haohao
3:s1    i=2    n=2
nimei=3
gunsn=3
nihao
4:j    i=3    n=3
hahn=4
nihao
5:构造块    i=4    n=4
hahn=5
haohao
6:s2    i=5    n=5
nimei=6
gunsn=6
nihao
7:i    i=6    n=6
hahn=7
nihao
8:静态块    i=7    n=99
hahn=100
nihao
9:j    i=8    n=100
hahn=101
nihao
10:构造块    i=9    n=101
hahn=102
haohao
11:init    i=10    n=102
nimei=11
gunsn=103


解析:

 

1

2

3

4

   

  public static int k=0;

  public static StaticTest s1=new StaticTest("s1");

  public static StaticTest s2=new StaticTest("s2");


先加载静态成员变量,初始化为默认值,K为0,s1=null,s2=null,其他类似。
然后准备给静态变量赋值,赋值到s1,这出现个对象,然后就转向来创建这个对象来。
因为静态成员只初始化一次,所以静态成员不用初始化了。直接初始化实例变量和实例代码块。
因而输出

1

2

1:j    i=0    n=0   

2:构造块    i=1    n=1   


然后,最后构造函数初始化,所以

Java code?

1

3:s1    i=2    n=2



输出6:之前类似。然后创建两个对象后又回来了,接着初始化赋值。
赋值执行

 

1

2

  public static int i=print("i");

 public static int n=99;



此时已经初始化静态变量完毕。
下面应该初始化静态块
 static
    {
        print("静态块");
    }
然后所有静态都已经初始化完毕,然后初始化成员变量。最后调用构造方法。静态方法在第一次调用的时候就初始化。

 

在main方法中语句:(1)new StaticTest("init");和类的字段赋值语句(2)new StaticTest("s1");二者都是要创建类的对象。
main方法中的语句(1)执行的很晚很晚,因为main方法想要运行,系统发现类竟然还没载入,于是载入类并进行系统默认的初始化行为;但是这个系统初始化行为中间发生了递归初始化。
系统载入类,接着系统自动完成类的默认初始化,此时的值就是0值和null值两类;
既然是初始化,我们要注意两大类:静态的和非静态的;在载入、初始化的过程中,如果没有使用new 的方式创建对象,那么系统是不会对类的非静态变量进行 默认初始化的,即使是0值和null值,也没有,JVM根本就不会理会非静态变量。现在使用了new,那么初始化就会涉及到对非静态变量的初始化。
运行开始
main方法激发类的加载,紧接着系统对静态变量完成了默认初始化,静态对象类型是null值,普通类型是0值;非静态变量,还没有进行任何处理,连默认值也没有;此时JVM还没对非静态变量做任何处理;
首先对k进行初始化,k的系统默认初始化值是0,此时进行赋值,再次被赋值为0,
到了(2)系统此时发现s1是一个对象,值为null(这个null是系统默认初始化得到的),要对s1进行赋值;这个地方就发生了“在未完成初始化的类上调用new” 系统如何处理的呢?我的看法是:系统按照正常流程走,跟在其他地方使用new创建对象完全一样。
这里就是嵌套初始化或者叫做递归初始化:在初始化自己的过程中,初始化自己。
系统会进行类的加载,并进行静态变量的初始化,但是系统发现类的静态变量已经完成了初始化,此时是使用了new 创建对象会涉及到非静态变量的初始化,那么直接到 public int j=print("j"); ,执行非静态变量的初始化。

转载于:https://my.oschina.net/u/2822116/blog/704656

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值