1、有繼承關系的加載順序
關於關鍵字static,大家 都知道它是靜態的,相當於一個全局變量,也就是這個屬性或者方法是可以通過類來訪問,當class文件被加載進內存,開始初始化的時候,被static修飾的變量或者方法即被分配了內存,而其他變量是在對象被創建后,才被分配了內存的。
所以在類中,加載順序為:
1.首先加載父類的靜態字段或者靜態語句塊
2.子類的靜態字段或靜態語句塊
3.父類普通變量以及語句塊
4.父類構造方法被加載
5.子類變量或者語句塊被加載
6.子類構造方法被加載
父類代碼:
public class FuLei {
static int num = 5;//1.首先被加載
static{
System.out.println("靜態語句塊已經被加載"+num); //2.被加載
}
int count = 0; //5.被加載
{
System.out.println("普通語句塊"+count++);//6.被加載
}
public FuLei(){
System.out.println("父類的構造方法在這時候加載count="+count);//7.被加載
}
}
子類代碼:
public class ZiLei extends FuLei {
static{
System.out.println("靜態語句塊和靜態變量被初始化的順序與代碼先后順序有關"); //3.被加載
}
static int num = 45;//4.被加載
int numre = 0; //8.被加載
{
numre++;
System.out.println("numre"+numre);//9.被加載
}
public ZiLei(){
System.out.println("子類構造方法");//10.被加載
}
public static void main(String[] args){
ZiLei ht = new ZiLei();
}
}
console打印:
靜態語句塊已經被加載5
靜態語句塊和靜態變量被初始化的順序與代碼先后順序有關
普通語句塊0
父類的構造方法在這時候加載count=1
numre1
子類構造方法
注意
當class文件被加載進內存,開始初始化的時候,被static修飾的變量或者方法即被分配了內存,而其他變量是在對象被創建后,才被分配了內存的。
將子類代碼中的創建對象注釋掉
// ZiLei ht = new ZiLei();
console打印:
靜態語句塊已經被加載5
靜態語句塊和靜態變量被初始化的順序與代碼先后順序有關
2、沒有繼承關系的加載順序
代碼示例
public class Test {
public static void main(String[] args) {
new Test(); //4.第四步,new一個類,但在new之前要處理匿名代碼塊
}
static int num = 4; //2.第二步,靜態變量和靜態代碼塊的加載順序由編寫先后決定
{
num += 3;
System.out.println("b"); //5.第五步,按照順序加載匿名代碼塊,代碼塊中有打印
}
int a = 5; //6.第六步,按照順序加載變量
{ // 成員變量第三個
System.out.println("c"); //7.第七步,按照順序打印c
}
Test() { // 類的構造函數,第四個加載
System.out.println("d"); //8.第八步,最后加載構造函數,完成對象的建立
}
static { // 3.第三步,靜態塊,然后執行靜態代碼塊,因為有輸出,故打印a
System.out.println("a");
}
static void run() // 靜態方法,調用的時候才加載// 注意看,e沒有加載
{
System.out.println("e");
}
}
console打印:
a
b
c
d
3、注意
- 靜態代碼塊(只加載一次)
- 構造方法(創建一個實例就加載一次)
- 靜態方法,調用的時候才會加載,不調用的時候不會加載
- 靜態語句塊和靜態變量被初始化的順序與代碼先后順序有關