Java零基礎_學Java必備的學習筆記(十五)Java-static關鍵字(下)

這是我參與8月更文挑戰的第6天,活動詳情查看:8月更文挑戰java

接上篇Java-static關鍵字(上),今兒繼續寫完,這篇文章主要內容以下:程序員

  • Java static靜態代碼塊
  • Java static靜態方法

Java static靜態代碼塊

靜態代碼塊的語法格式是這樣的:markdown

類{
//靜態代碼塊
static{
java語句;
}
}
複製代碼

靜態代碼塊在類加載時執行,而且只執行一次。開發中使用很少,但離了它有的時候還真是無法寫代碼。工具

靜態代碼塊其實是java語言爲程序員準備的一個特殊的時刻,這個時刻就是類加載時刻,若是你想在類加載的時候執行一段代碼,那麼這段代碼就有的放矢了。post

例如咱們要在類加載的時候解析某個文件,而且要求該文件只解析一次,那麼此時就能夠把解析該文件的代碼寫到靜態代碼塊當中了。測試

咱們來測試一下靜態代碼塊:this

public class StaticTest01 {
	//靜態代碼塊
	static{
		System.out.println(2);
	}
	//靜態代碼塊
	static{
		System.out.println(1);
	}
	//main方法
	public static void main(String[] args) {
		System.out.println("main execute!");
	}
	//靜態代碼塊
	static{
		System.out.println(0);
	}
}
複製代碼

運行結果以下圖所示:spa

圖1:靜態代碼塊運行結果設計

經過以上的測試能夠得知一個類當中能夠編寫多個靜態代碼塊(儘管大部分狀況下只編寫一個),而且靜態代碼塊遵循自上而下的順序依次執行,因此有的時候放在類體當中的代碼是有執行順序的(大部分狀況下類體當中的代碼沒有順序要求,方法體當中的代碼是有順序要求的,方法體當中的代碼必須遵照自上而下的順序依次逐行執行),另外靜態代碼塊當中的代碼在main方法執行以前執行,這是由於靜態代碼塊在類加載時執行,而且只執行一次。code

再來看一下如下代碼:

public class StaticTest02 {
	int i = 100;
	static{
		System.out.println(i);
	}
}
複製代碼

編譯結果以下圖所示:

圖2:靜態代碼塊中訪問實例變量編譯報錯

爲何編譯報錯呢?

那是由於i變量是實例變量,實例變量必須先建立對象才能訪問,靜態代碼塊在類加載時執行,這個時候對象尚未建立呢,因此i變量在這裏是不能這樣訪問的。能夠考慮在i變量前添加static,這樣i變量就變成靜態變量了,靜態變量訪問時不須要建立對象,直接經過「類」便可訪問,例如如下代碼:

public class StaticTest02 {
	static int i = 100;
	static{
		System.out.println("靜態變量i = " + i);
	}
	public static void main(String[] args) {
	}
}
複製代碼

運行結果以下圖所示:

圖3:靜態代碼塊中訪問靜態變量

代碼修改成這樣呢?

public class StaticTest02 {
	static{
		System.out.println("靜態變量i = " + i);
	}
	static int i = 100;
}
複製代碼

編譯報錯了,請看下圖:

圖4:編譯報錯信息

經過測試,能夠看到有的時候類體當中的代碼也是有順序要求的(類體當中定義兩個獨立的方法,這兩個方法是沒有前後順序要求的),靜態代碼塊在類加載時執行,靜態變量在類加載時初始化,它們在同一時間發生,因此必然會有順序要求,若是在靜態代碼塊中要訪問i變量,那麼i變量必須放到靜態代碼塊以前。

Java static靜態方法

方法在什麼狀況下會聲明爲靜態的呢?方法實際上描述的是行爲動做,我認爲當某個動做在觸發的時候須要對象的參與,這個方法應該定義爲實例方法,例如:每一個玩籃球的人都會打籃球,可是你打籃球和科比打籃球最終的效果是不同的,顯然打籃球這個動做存在對象差別化,該方法應該定義爲實例方法。

再如:每一個高中生都有考試的行爲,可是你考試和學霸考試最終的結果是不同的,一個上了「家裏蹲大學」,一個上了「清華大學」,顯然這個動做也是須要對象參與才能完成的,因此考試這個方法應該定義爲實例方法。

以上描述是從設計思想角度出發來進行選擇,其實也能夠從代碼的角度來進行判斷,當方法體中須要直接訪問當前對象的實例變量或者實例方法的時候,該方法必須定義爲實例方法,由於只有實例方法中才有this,靜態方法中不存在this。

請看代碼:

public class Customer {
	String name;
	public Customer(String name){
		this.name = name;
	}
	public void shopping(){
		//直接訪問當前對象的name
		System.out.println(name + "正在選購商品!");
		//繼續讓當前對象去支付
		pay();
	}
	public void pay(){
		System.out.println(name + "正在支付!");
	}
}
複製代碼
public class CustomerTest {
	public static void main(String[] args) {
		Customer jack = new Customer("jack");
		jack.shopping();
		Customer rose = new Customer("rose");
		rose.shopping();
	}
}
複製代碼

運行結果以下圖所示:

圖5:運行結果

在以上的代碼中,不一樣的客戶購物,最終的效果都不一樣,另外在shopping()方法中訪問了當前對象的實例變量name,以及調用了實例方法pay(),因此shopping()方法不能定義爲靜態方法,必須聲明爲實例方法。

另外,在實際的開發中,「工具類」當中的方法通常定義爲靜態方法,由於工具類就是爲了方便你們的使用,將方法定義爲靜態方法,比較方便調用,不須要建立對象,直接使用類名就能夠訪問。

請看如下工具類,爲了簡化「System.out.println();」代碼而編寫的工具類:

public class U {
	public static void p(int data){
		System.out.println(data);
	}
	public static void p(long data){
		System.out.println(data);
	}
	public static void p(float data){
		System.out.println(data);
	}
	public static void p(double data){
		System.out.println(data);
	}
	public static void p(boolean data){
		System.out.println(data);
	}
	public static void p(char data){
		System.out.println(data);
	}
	public static void p(String data){
		System.out.println(data);
	}
}
複製代碼

運行結果以下圖所示:

圖6:測試工具類

相關文章
相關標籤/搜索