1. 程式人生 > 實用技巧 >關鍵字static與類的初始化

關鍵字static與類的初始化

目錄

1、static關鍵字基本概念

方便在沒有建立物件的情況下來進行呼叫。

即被static關鍵字修飾的不需要建立物件去呼叫,直接根據類名就可以去訪問。

static關鍵字修飾類(內部類)

java裡面static一般用來修飾成員變數或函式。但有一種特殊用法是用static修飾內部類,普通類是不允許宣告為靜態的,只有內部類才可以。

public class StaticClass {
    public static class InnerClass{
        InnerClass(){
            System.out.println("=========靜態內部類===========");
        }
        public void InnerMethod(){
            System.out.println("=========靜態內部方法===========");
        }
    }
    public static void main(String[] args){
        // 直接通過StaticTest類名訪問靜態內部類InnerClass
        InnerClass inner=new StaticClass.InnerClass();
        inner.InnerMethod();
    }
}

如果沒有用static修飾InterClass,則只能new 一個外部類例項。
再通過外部例項建立內部類。

public class StaticClass {
    public class InnerClass{
        InnerClass(){
            System.out.println("=========靜態內部類===========");
        }
        public void InnerMethod(){
            System.out.println("=========靜態內部方法===========");
        }
    }
    public static void main(String[] args){
        // new 一個外部類例項。再通過外部例項建立內部類。
        StaticClass classInner=new StaticClass();
        StaticClass.InnerClass inner=classInner.new InnerClass();
        inner.InnerMethod();
    }
}

static關鍵字修飾方法

修飾方法的時候,其實跟類一樣,可以直接通過類名來進行呼叫:

public class StaticMethod {
    public static void test(){
        System.out.println("======靜態方法======");
    }
    public static void main(String [] args){
        // 方式一:直接通過類名
//        StaticMethod.test();
        // 方式二:
        StaticMethod fdd=new StaticMethod();
        fdd.test();
    }
}

static關鍵字修飾變數

被static修飾的成員變數叫做靜態變數,也叫做類變數,說明這個變數是屬於這個類的,而不是屬於是物件,沒有被static修飾的成員變數叫做例項變數,說明這個變數是屬於某個具體的物件的。

static關鍵字修飾程式碼塊

父類靜態變數--父類靜態程式碼塊--子類靜態變數--子類靜態程式碼塊--父類普通變數--父類普通程式碼塊--父類建構函式--子類普通變數--子類普通程式碼塊--子類建構函式

public class Father {
    static{
        System.out.println("Father static");
    }
    public Father(){
        System.out.println("Father Constructor");
    }
}
public class Son  extends Father{
    static{
        System.out.println("Son static");
    }
    public Son(){
        System.out.println("Son Constructor");
    }
    public static void main(String [] args){
        new Son();
    }
}
// 輸出:
Father static
Son static
Father Constructor
Son Constructor

靜態物件的執行級別是一樣的,因此會從最靠上的靜態物件開始執行,而且每個靜態方法只會在類生命的時候初始化一次。

類的初始化

靜態程式碼塊或者靜態變數是物件載入的時候進行,且只加載一次。而成員變數或者普通程式碼塊 每次例項的時候都會執行一次,而且都優先於構造方法。

public class ParentClass {
    //    父類靜態成員
    static int num = 0;// 1
    String name = "qqqqqq";//4
    static String name2 = "wwwwwwwwwww";//2
    {
        System.out.println("name1:" + name);//5
        System.out.println("這裡是塊1============");
    }
    ParentClass(){
        System.out.println("這裡是建構函式*************");//6
    }
    static {
        num += 1;
        System.out.println("name2:" + name2);
        System.out.println("這裡是靜態初始化塊*************" + num);
    }
    static ParentClass parentClass = new ParentClass();//每次例項化一個物件,都需要進行類的初始化
}
public class TestClass {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ParentClass pa = new ParentClass();

    }
}
輸出:
name2:wwwwwwwwwww
這裡是靜態初始化塊*************1
name1:qqqqqq
這裡是塊1============
這裡是建構函式*************
name1:qqqqqq
這裡是塊1============
這裡是建構函式*************

2.基於上例,理解下類的初始化

1)類的載入:

JVM: Java Virtual Machine(Java虛擬機器

引入Java語言虛擬機器後,Java語言在不同平臺上執行時不需要重新編譯。Java語言使用Java虛擬機器遮蔽了與具體平臺相關的資訊,使得Java語言編譯程式只需生成在Java虛擬機器上執行的目的碼(位元組碼),就可以在多種平臺上不加修改地執行。

代表jvm將java檔案編譯成class檔案後,以二進位制流的方式存放到執行時資料的方法區中,並在java的堆中建立一個java.lang.Class物件,用來指向存放在方法堆中的資料結構。

2) 類的初始化:

類從被載入到虛擬機器記憶體中開始,到卸載出記憶體為止,它的整個生命週期包括:載入、驗證、準備、解析、初始化、使用和解除安裝七個階段。其中驗證、準備、解析3個部分統稱為連線。類載入的過程包括了載入、驗證、準備、解析、初始化五個階段。

3) 類載入有三種方式:

1、命令列啟動應用時候由JVM初始化載入

2、通過Class.forName()方法動態載入

3、通過ClassLoader.loadClass()方法動態載入