阿里的一道靜態方法和靜態代碼塊牛逼筆試題

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");  
    }  
}spa


運行結果:.net

 

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=103code


解析:對象

 

1遞歸

2ip

3ci

4get

   

  public static int k=0;it

  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"); ,執行非靜態變量的初始化。

相關文章
相關標籤/搜索