——static
static關鍵字是很多同學在編寫代碼和閱讀代碼時碰到的比較難以了解的一個關鍵字,也是各大公司的面試官喜歡在面試時問到的知識點之一。
static修飾符可以用來修飾類的成員變量、成員方法和代碼塊。
用static修飾的成員變量表示靜态變量,可以直接通過類名來通路;
用static修飾的成員方法表示靜态方法,可以直接通過類名來通路;
用static修飾的程式代碼表示靜态代碼塊,當Java虛似機加載類時,就會執行該代碼塊。
被static所修飾的成員變量和成員方法表明歸某個類所有,它不依賴于類的特定執行個體,被類的所有執行個體共享。
——static變量(靜态變量)
形式和執行個體變量類似,在執行個體變量前面加static關鍵字;
——static變量和執行個體變量的差別:
static變量對于每個類而言在記憶體中隻有一個,能被類的所有執行個體所共享;執行個體變量對于每個類的每個執行個體都有一份,它們之間互不影響;
Java虛拟機在加載類的過程中為static變量配置設定記憶體,執行個體變量在加載完類後建立對象時配置設定記憶體;
static變量可以直接通過類名通路,執行個體變量通過引用類型變量通路;
Q1:下面程式運作完畢後,count1、count2對應的值是多少。
public class Counter {
public int count1 = 0;
public static int count2 = 0;
public static void main(String[] args) {
CountercounterA = new Counter();
CountercounterB = new Counter();
counterA.count1++;
counterA.count2++;
counterB.count1++;
counterB.count2++;
}
}
練習:統計一個類建立執行個體的個數;
——總結:
static變量也稱作靜态變量,靜态變量和非靜态變量的差別是:靜态變量被所有的對象所共享,在記憶體中隻有一個副本,它當且僅當在類初次加載時會被初始化。而非靜态變量是對象所擁有的,在建立對象的時候被初始化,存在多個副本,各個對象擁有的副本互不影響。
——static方法(靜态方法)
static方法一般稱作靜态方法,由于靜态方法不依賴于任何對象就可以進行通路,是以對于靜态方法來說,是沒有this的,因為它不依附于任何對象,既然都沒有對象,就談不上this了。并且由于這個特性,在靜态方法中不能通路類的非靜态成員變量和非靜态成員方法,因為非靜态成員方法/變量都是必須依賴具體的對象才能夠被調用。
但是要注意的是,雖然在靜态方法中不能通路非靜态成員方法和非靜态成員變量,但是在非靜态成員方法中是可以通路靜态成員方法/變量的。
另外記住,即使沒有顯示地聲明為static,類的構造器實際上也是靜态方法。
——static方法注意事項:
1、不能使用this關鍵字;
this代表什麼?this代表目前對象,但是對于靜态方法來說,是沒有this的,因為它不依附于任何對象,既然都沒有對象,就談不上this了。
2、不能使用super關鍵字;
super關鍵字用來通路目前執行個體從父類中繼承的方法和屬性。super關鍵字與類的特定執行個體相關;
3、靜态方法必須被實作;
靜态方法用來表示某個類所特有的功能,這種功能的實作不依賴于類的具體執行個體,也不依賴于它的子類。既然如此,目前類必須為靜态方法提供實作。
4、父類的靜态方法不能被子類覆為非靜态方法;
5、父類的非靜态方法不能被子類覆寫為靜态方法;
——static代碼塊(靜态代碼塊)
static關鍵字還有一個比較關鍵的作用就是用來形成靜态代碼塊以優化程式性能。static塊可以置于類中的任何地方,類中可以有多個static塊。在類初次被加載的時候,會按照static塊的順序來執行每個static塊,并且隻會執行一次。
很多時候會将一些隻需要進行一次的初始化操作都放在static代碼塊中進行。
構造代碼塊:
在類中方法外出現;多個構造方法方法中相同的代碼存放到一起,每次調用構造都執行,并且在構造方法前執行
Q1:static關鍵字會改變類中成員的通路權限嗎?
Q2:能通過this通路靜态成員變量嗎?
Q3:為什麼main方法要加static修飾
[1]
——靜态導入
靜态導入也是JDK5.0引入的新特性。
要使用靜态成員(方法和變量)我們必須給出提供這個靜态成員的類。使用靜态導入可以使被導入類的靜态變量和靜态方法在目前類中可以直接使用,使用這些靜态成員無需再在前面寫上他們所屬的類名。
java都是以類作為程式的組織單元,當我們要執行的時候,我們并不知道這個main方法會放到哪個類當中,也不知道是否是要産生類的一個對象,為了解決程式的運作問題,我們将這個main方法定義為static,這樣的話,當我們在執行一個java代碼的時候,我們在指令提示符中寫:java Point(Point為一個類),解釋器就會在Point這個類當中,去調用這個靜态的main方法,而不需要産生Point這個類的對象,當我們加載Point這個類的時候,那麼main方法也被加載了,作為我們java程式的一個入口。
public被jvm調用,通路權限足夠大。
static被jvm調用,不用建立對象,直接類名通路
void被jvm調用,不需要給jvm傳回值
main一個通用的名稱,雖然不是關鍵字,但是被jvm識别
String[]args 以前用于接收鍵盤錄入的