1 靜態方法
前面我們瞭解了靜態成員變量的一些使用的方式,現在我們接着探討一下靜態方法的相關內容,並瞭解一下靜態方法的使用情況。
1.1 靜態方法和一般方法的定義方法
在類中我們可以定義類的方法,如果當一個方法的前面加了關鍵字Static,也當方法使用靜態修飾符時,我們則稱這個方法爲靜態方法,沒有這個關鍵字,則不是靜態方法。還是以Car類爲例,定義一個靜態方法stop(),和一個非靜態方法show(),具體看下面代碼所示。
public class Car {
publicString color;
publicstatic String myColor="white";
Car(Stringcolor){
this.color=color;
}
//一般方法show()
voidshow(String color,String myColor){
System.out.println("汽車的顏色是"+color);
}
//靜態方法stop()
static voidstop() {
System.out.println("汽車停了下來。");
}
publicstatic void main(String[] args) {
Carcar1=new Car(“blue”);
car1.show();
car1.stop();
car car2=new Car(“yellow”);
car2.show();
car2.stop();
}
}
運行結果爲:
汽車的顏色是blue
汽車停了下來。
汽車的顏色是yellow
汽車停了下來。
通過以上代碼,我們發現除了在靜態方法前增加了靜態修飾符之外,靜態方法和一般方法一樣都能夠被對象所調用。這是靜態方法與一般方法的相同之處。
1.2 什麼情況下使用靜態方法?
1.2.1 靜態方法不調用成員變量
在Car類中存在兩個方法,一個方法是show(),另一個方法是stop()。假設這兩個方法都是普通方法,那麼在定義對象的時候,就需要給給兩個方法分配相應的內存地址空間。
從代碼中我們可以得出,show()訪問了成員變量color和靜態成員變量myColor,而stop()方法沒有訪問任何的成員變量。也就是說給在構建對象的時候,給方法show()和方法stop()都分配內存空間,而方法show()分配內存空間並沒有用來存放對象的屬性,那麼這個內存空間就白白浪費了。具體如下圖所示。
圖1 定義一般方法方法後在內存中的使用情況圖
爲了解決這種浪費內存空間的情況,我們可以將一個方法不需要訪問成員變量的情況時,將該方法前面添加靜態修飾符,定義爲靜態方法。靜態方法只需要在內存中分配一次內存空間,而且這個內存空間屬於數據共享區,與對象的內存空間不同,同時該類的所有對象都可以調用該靜態方法。使用靜態方法就能去掉一般方法的弊端,節約內存空間。
圖2 定義靜態方法後內存空間使用情況圖
1.2.2 在類中直接調用方法
假設不構建類的對象,而想調用方法該如何實現?
我們知道一般方法都需要先構建對象,然後通過對象才能能調用方法,這達不到我們的要求。這時候就使用靜態方法,才能夠實現這個需求。具體以下面例子爲例。
public class Car { publicString color; publicstatic String myColor="white"; Car(){ } Car(Stringcolor){ this.color=color; } //一般方法show() voidshow(){ System.out.println("汽車的顏色是"+this.color); } //靜態方法stop() static voidstop() { System.out.println("汽車停了下來。"); } publicstatic void main(String[] args) { newCar().stop(); } }
運行結果爲:
汽車停了下來。
我們發現沒有構建對象,但是成功的調用了靜態方法。不用構建對象,就不需要給對象分配內存空間,所以使用類來調用靜態方法,這同樣達到了節約內存空間的效果。
1.3 是不是任意方法都能定義爲靜態方法?
靜態方法節約內存,那是不是所有的方法都定義爲靜態方法來節約內存空間呢?還是以Car類爲例,將show()方法定義爲靜態方法看會發生什麼。
public class Car { publicString color; publicstatic String myColor="white"; Car(){ } Car(Stringcolor){ this.color=color; } //靜態方法show() staticvoid show(){ System.out.println("汽車的顏色是"+color); } //靜態方法stop() static voidstop() { System.out.println("汽車停了下來。"); } publicstatic void main(String[] args) { newCar().show(); new Car().stop(); } }
編譯時,發現會報錯
報錯內容:Cannot make astatic reference to the non-static field color。
這是因爲show()方法中調用了非靜態變量color,而靜態方法只能調用靜態變量,所以會報錯。
如果我們將show()方法中的代碼進行修改,改爲以下內容:
staticvoid show(){
System.out.println("汽車的顏色是"+myColor);
}
運行結果爲:
汽車的顏色是white
汽車停了下來。
我們將show()方法中訪問的變量更換爲靜態成員變量後,發現可以編譯通過,並正常運行。
如果我們將show()方法中的代碼進行修改,改爲以下內容:
staticvoid show(){
System.out.println("汽車的顏色是"+this.myColor);
}
編譯時,發現會報錯。
報錯內容:Cannotuse this in a static context
通過以上可以得出結論,不是所有的方法都能夠定義爲靜態方法的,只有不訪問成員變量或者訪問靜態成員變量的方法才能夠定義爲靜態方法,不使用this關鍵字的方法才能定義爲靜態方法。
爲什麼靜態方法不能訪問非靜態成員變量呢?這是因爲靜態方法是隨着類的加載而加載的,靜態方法先與對象存在於內存中,無法訪問後出現的對象中的屬性和方法,所以靜態方法無法訪問非靜態方法或變量。而靜態變量隨着類的加載而加載,所以靜態方法可以訪問靜態變量。
爲什麼在靜態方法中不能使用this關鍵字?這是因爲this關鍵字是指向對象的地址,而使用類調用靜態方法的時候,並沒有生成對象,所以this關鍵字就會出現指向不明確的情況,所以在java中靜態方法不能使用this關鍵字。
1.4 靜態方法都能被誰調用?
定義完靜態方法後,就可以調用靜態方法。那麼靜態方法都能被誰調用呢?在前面我們使用了“new Car().stop();”語句來調用靜態方法stop(),這說明使用類可以調用靜態方法。
1.4.1 對象調用靜態方法
靜態方法也是方法的一種,使用對象可以調用靜態方法嗎?我們用下面的代碼來舉例:
public class Car { publicString color; publicstatic String myColor="white"; Car(){ } Car(Stringcolor){ this.color=color; } //一般方法show() voidshow(){ System.out.println("汽車的顏色是"+color); } //靜態方法stop() static voidstop() { System.out.println("汽車停了下來。"); } publicstatic void main(String[] args) { Carcar=new Car(); Car.stop(); } }
運行結果如下:
汽車停了下來。
根據運行結果,我們得以得出結論,對象可以直接調用靜態方法。
1.2.2 非靜態方法調用靜態方法
非靜態方法可以調用靜態方法嗎?我們用下面的代碼來舉例。
public class Car { publicString color; publicstatic String myColor="white"; Car(){ } Car(Stringcolor){ this.color=color; } //一般方法show() voidshow(){ System.out.println("汽車的顏色是"+ myColor); Stop(); } //靜態方法stop() static voidstop() { System.out.println("汽車停了下來。"); } publicstatic void main(String[] args) { Carcar=new Car(); Car.show(); } }
運行結果如下:
汽車的顏色是white
汽車停了下來。
通過運行結果我們可以得出結論,非靜態方法show()成功的調用了靜態方法stop()。
通過以上的幾個例子,我們得出類、對象和非靜態方法都能夠成功的調用靜態方法。