關鍵字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()方法動態載入