文章為原創,轉載請說明來源,謝謝。
作者:cha1R
要搞清楚這個問題,我們需要清楚他們之間有什么區別,有什么優勢和劣勢。
首先看看靜態與非靜態方法的區別:
靜態方法 | 實例方法
1、靜態方法可以通過“類.方法()”調用 | 要在對象實例化后使用對象調用
2、只能使用靜態變量和局部變量 | 所有變量都可以使用
3、靜態方法不能被子類重寫 | 實例方法可以
4、接口不能定義靜態方法 | 實例方法可以
從上面區別來看,靜態方法只有一個優勢,就是調用的時候不用實例化,其他情況下跟實例方法相比都是處於劣勢。那么我們在什么情況下會使用到靜態方法?相信大家第一時間會想到一樣的東西,工具類Util。工具類給我們開發帶來了大大的方便,歸根到底是“不用實例化就能用”的功勞。這是靜態方法的一個優勢。
而靜態方法的劣勢也很明顯,局限性很大,不能重寫,不能引用普通變量,接口不能定義等等。。。可能還有很多我沒列舉出來。
那究竟什么時候該用靜態方法?我們就要最大化利用其優勢而避其缺點:
1、一個方法完成一個獨立的功能,而且不會干擾到其他方法或變量,則即使刪掉這個方法,對其他東西都沒有任何影響。
2、不依賴構造方法,不依賴接口,不依賴繼承。(這也是為什么越學面向對象,越會糾結這個問題)
舉個例子:String類即使刪掉 static valueOf(Object obj)方法,也不會影響實例方法chatAt(int index)的使用。當然它可能會影響其他重載的valueOf方法。
至於現在網上很多資料都有一個誤區,就是說靜態方法一開始加載,會占用內存,而實例方法不會。這個說話其實是錯誤的,它們都是一樣一開始就會加載,而且只會占用一份內存。因為方法不是變量,它只需要有一份內存就夠了。而變量則不一樣
-----------------------------------------------------------------------------------------------------------------------------------------------------------
下面來看看靜態變量與非靜態變量
靜態變量 | 非靜態變量
1、可以通過“類.變量”來引用。 | 只能通過實例對象來引用。
2、程序運行時分配內存 | 類實例化時分配內存。
3、只有一份內存被分配 | 有多少個類被實例化,就有多少個該類的變量那么多份內存被分配。
4、靜態變量定義后必須聲明初始化 | 非靜態變量可以延遲初始化。
其他.....
很明顯,靜態變量擁有的優勢不少,第一點不用說。第2、3點可以利用它來做一個整個程序的全局變量,因為任何修改都只會指向同一份內存。
而第3點優勢恰好就是我們的“餓漢式單例模式”的一個最簡單的實現。
我們也可以通過靜態變量+靜態方法的組合來封裝一個完整的懶漢式單例模式。
public class Singleton{ private static Singleton singleton = null; public static Singleton getInstance(){ if(singleton==null){ synchronized(Singleton.class){ if(singleton==null){ singleton = new Singleton(); } } } return singleton; } }
在使用靜態變量的時候,要注意一個線程問題,因為所有人都在操作它。