1 靜態代碼塊
下面介紹一種不是很常見的靜態修飾符的使用方法。當我們需要一個類,這個類的構造函數是私有的,那麼這個類之外其他程序就不能夠創建這個類的對象。那麼如何初始化這個類呢?
爲了解決這個問題,我們可以使用前文中的靜態成員變量或者靜態方法來初始化類。在類的加載過程中,靜態成員變量和靜態方法同時也就加載完成了。除了上面的兩種方法還有一種更加簡單的方法,就是在類中使用靜態代碼塊。靜態代碼塊不是一個方法,它的寫法很簡單,如下:
public class Car { privateCar() { } static{ Stringcolor="green"; System.out.println("汽車的顏色是:"+color); System.out.println("汽車停下來了"); } publicstatic void main(String[] args) { } }
運行結果如下:
汽車的顏色是:green
汽車停下來了。
這說明在類加載過程中就同時加載了靜態代碼塊中的程序。那麼靜態代碼塊中能夠寫那些內容呢?我們以下面代碼爲例說明:
public class Car { privateCar() { } Stringcolor="green"; staticString myNewColor="black"; static{ StringmyColor="white"; newCar().show(); stop(); System.out.println("我的車的顏色是:"+myColor); System.out.println("我的車的新顏色是:"+myNewColor); } staticvoid stop(){ System.out.println("汽車停下來了"); } voidshow() { System.out.println("汽車的顏色是:"+this.color); } public staticvoid main(String[] args) { } }
運行結果如下:
汽車的顏色是:green
汽車停下來了。
我的車顏色是:white
我的車的新顏色是:black
從代碼中可以得出以下結論:
1、只能直接調用靜態方法,而不能直接調用非靜態方法;
2、如果需要調用非靜態方法同樣需要構建對象後才能調用非靜態方法;
3、在代碼塊中聲明的變量是局部變量,所以只能聲明一般變量而不能聲明靜態成員變量。
4、代碼塊中可以直接訪問靜態成員變量。
通過上述代碼,我們發現靜態代碼塊還是功能強大的,能夠在不構建對象的情況下,初始化類,解決我們上面提到的需求。
2 靜態內部類
如果在一個類中再定義一個類,就將在類中再定義的那個類稱爲內部類。雖然類不能使用靜態修飾符,但是內部類卻是可以使用靜態修飾符的一個特例。
2.1 定義靜態內部類
當我們在定義一個內部類的時候,在內部類的前面增加了靜態修飾符static,那麼這個類就稱爲靜態內部類。如下代碼所示,CarWindow類就是靜態內部類,CarDoor類就是非靜態內部類。
public class Car { publicstatic class CarWindow{ Public void show(){ System.out.println("車玻璃的顏色是黑色。"); } } Publicclass CarDoor{ Public void show(){ System.out.println("車門的顏色是白色。"); } } publicstatic void main(String[] args) { Car.CarDoorcarDoor=new Car().new CarDoor(); carDoor.show(); } }
要訪問非靜態類中的show()方法,需要定義對象,然後再通過對象調用show()方法。由於存在外部類和內部類兩個類,所以在創建對象的時候,先要創建外部類對象,然後通過外部類對象創建內部類對象。在main()方法中,通過“Car.CarDoor carDoor=new Car().new CarDoor();”語句創建了carDoor對象,然後通過carDoor對象調用show()方法。
運行結果爲:
車門的顏色是白色的。
要訪問靜態內部類與訪問非靜態內部類略有不同,主要包括訪問靜態內部類中的非靜態成員和靜態內部類中的靜態成員。下面將分開介紹。
2.2 訪問靜態內部類中的非靜態成員
在靜態內部類CarWindow中定義個一個非靜態方法show(),如果需要訪問這個方法,我們先需要訪問外部類Car。不過與訪問非靜態內部類不同的是,訪問靜態內部類時,由於靜態內部類的加載與外部類的加載同時,所以不需要創建外部類對象,而是直接創建內部類對象,在使用內部類對象訪問非靜態方法show()。
要訪問CarWindow中定義的非靜態方法show(),需要修改main()方法如下:
public staticvoid main(String[] args) { Car.CarDoorcarDoor=new Car().new CarDoor(); carDoor.show(); Car.CarWindowcarWindow=new Car.CarWindow(); window.show(); }
運行結果爲:
車門的顏色是白色的。
車玻璃的顏色是黑色的。
2.3 訪問靜態內部類中的靜態成員
當在靜態內部類中存在靜態成員,例如靜態成員變量或靜態方法,這時訪問靜態內部類的靜態成員就更加簡單。因爲靜態內部類隨着外部類的加載而加載,而內部類中的靜態成員隨着內部類加載而加載。
也就是說當外部類加載完成後,靜態內部類以及靜態成員也就同時完成了加載。所以不需要對象就可以實現靜態內部類中的靜態成員的訪問,直接使用類名就可以完成訪問。
將上面代碼中靜態內部類CarWindow的show()方法改爲靜態方法,那麼在main()方法中做如下修改:
public staticvoid main(String[] args) { Car.CarWindow.showCarWindow(); }
運行結果爲:
車玻璃的顏色是黑色的。
雖然訪問靜態內部類的靜態方法用起來很簡單,但是當定義爲靜態時,就存在了局限性。在前文中提到過靜態方法只能訪問靜態成員,所以不是什麼情況都適合使用靜態修飾符的。