由阿里巴巴筆試題看java加載順序

1、阿里巴巴筆試題:數組

 1 public class T  implements Cloneable {
 2     public static int k = 0;
 3     public static T t1 = new T("t1");
 4     public static T t2 = new T("t2");
 5     public static int i = print("i");
 6     public static int n = 99;
 7 
 8     public int j = print("j");
 9     
10     {
11         print("構造塊");
12     }
13 
14     static {
15         print("靜態塊");
16     }
17 
18     public T(String str) {
19         System.out.println((++k) + ":" + str + "    i=" + i + "  n=" + n);
20         ++n;
21         ++i;
22     }
23 
24     public static int print(String str) {
25         System.out.println((++k) + ":" + str + "   i=" + i + "   n=" + n);
26         ++n;
27         return ++i;
28     }
29     
30     public static void main(String[] args) {
31         
32     }
33 }

 

2、加載過程分析:函數

執行main時,先加載所在類,聲明靜態變量,並初始化靜態變量執行靜態代碼塊(按順序執行)spa

初始化到t1時,暫停類加載,先實例化,此時k=0,而i,n都未初始化,系統默認值爲0
初始化j時,k自增爲1,i,n爲0,輸出「1:j i=0 n=0」,n,i自增爲1
執行代碼塊,輸出「2:構造塊 i=1 n=1」,n,i自增爲2
執行構造函數,輸出「3:t1 i=2 n=2」,n,i自增爲3code

初始化到t2時,暫停類加載,先實例化,此時k=3,i,n都還未初始化,但已自增爲3
初始化j時,k自增爲4,i,n未初始化爲3,輸出「4:j i=3 n=3」,n,i自增爲4
執行代碼塊,輸出「5:構造塊 i=4 n=4」,n,i自增爲5
執行構造函數,輸出「6:t2 i=5 n=5」,n,i自增爲6對象

初始化i,輸出「7:i i=6 n=6」,n,i自增爲7,返回自增後的i賦值給i
初始化n,賦值99
執行靜態塊,輸出「8:靜態塊 i=7 n=99」,i自增爲8,n自增爲100blog

完成類加載繼承

3、涉及知識點:
1.類加載過程:
加載某類前先加載其父類
加載某類時,先聲明靜態成員變量,初始化爲默認值,再初始化靜態成員變量執行靜態代碼塊
初始化靜態成員變量執行靜態代碼塊時,是按順序執行(初始化靜態成員變量的本質就是靜態代碼塊)接口

2.實例化過程:
對某類實例化前,先對其父類進行實例化
實例化某類時,先聲明成員變量,初始化爲默認值,再初始化成員變量執行代碼塊
初始化成員變量執行代碼塊時,是按順序執行字符串

3.在某類加載過程當中調用了本類實例化過程(如new了本類對象),則會暫停類加載過程先執行實例化過程,執行完畢再回到類加載過程編譯器


4.類的主動使用與被動使用:
主動使用例子:
1):最爲經常使用的new一個類的實例對象
2):直接調用類的靜態方法。
3):操做該類或接口中聲明的非編譯期常量靜態字段
4):反射調用一個類的方法。
5):初始化一個類的子類的時候,父類也至關於被程序主動調用了
(若是調用子類的靜態變量是從父類繼承過來並無複寫的,那麼也就至關於只用到了父類的東東,和子類無關,
因此這個時候子類不須要進行類初始化)。
6):直接運行一個main函數入口的類。

全部的JVM實現,在首次主動使用某類的時候纔會加載該類。

被動使用例子:
7):子類調用父類的靜態變量,子類不會被初始化。只有父類被初始化。對於靜態字段,只有直接定義這個字段的類纔會被初始化.
8):經過數組定義來引用類,不會觸發類的初始化,如SubClass[] sca = new SubClass[10];
9):訪問類的編譯期常量,不會初始化類

5.編譯期常量:
寫到類常量池中的類型是有限的:String和幾個基本類型
String值爲null時,也不會寫到類常量池中
使用new String("xx")建立字符串時,獲得的字符串不是類常量池中的

6.對於經過new產生一個字符串(假設爲 」china」 )時,會先去常量池中查找是否已經有了 」china」 對象,
若是沒有則在常量池中建立一個此字符串對象,而後堆中再建立一個常量池中此 」china」 對象的拷貝對象。

7.類成員變量纔會有默認的初始值
byte:0(8位)
short:0(16位)
int:0(32位)
long:0L(64位)
char:\u0000(16位),表明NULL
float:0.0F(32位)
double:0.0(64位)
boolean: flase

8.局部變量聲明之後,Java 虛擬機不會自動的爲它初始化爲默認值。
所以對於局部變量,必須先通過顯示的初始化,才能使用它。
若是編譯器確認一個局部變量在使用以前可能沒有被初始化,編譯器將報錯。

9.數組和String字符串都不是基本數據類型,它們被看成類來處理,是引用數據類型。引用數據類型的默認初始值都是null

相關文章
相關標籤/搜索