static 和new物件方法的區別
我們拋開static成員使用的特點,理解一下static修飾成員的意義。
類的一個成員被static修飾後,該成員就屬於類的成員了,被所有物件共享,如果成員是成員變數,那麼該成員以及該成員的值就被所有物件所共享;如果成員是成員方法,那麼該方法就被所有物件共享;相反如果成員沒有用static修飾,那麼每個物件就有自己的成員,這時可以說,每個物件的成員是他私有的,注意這和許可權控制裡的私有許可權是兩碼事。可以想象,共享的方法只能訪問共享的成員,是無法訪問物件私有的成員的,而物件私有的成員方法是可以訪問共享的成員的。打個比方,就像我們給公家幹活肯定花的是公家的錢,絕不會花私人的錢,而給自己幹活時,卻可以花公家的錢,只要公家不追究。這也就是為什麼static修飾的成員只能訪問static修飾的成員,如static修飾的成員方法,static修飾的初始化塊還有static修飾的內部類均如此。也有的人把static理解為靜態的或全域性的,其實差不多,因為靜態的對應者動態的,全域性的對應著區域性的,看你從哪個角度去理解。
在實際開發中,之所以給類定義成員變數,就是因為該類有不同狀態的物件,比如我們定義人這個類,一般會定義年齡、姓名等屬性,然後不同的人(這裡就是人這個類的物件了)雖然都有年齡和姓名,但各有各的年齡,各有各的姓名,這就是上面說的每個物件的成員是該物件私有的。如果把年齡和姓名定義成static的,那就導致所有的人都有相同的年齡和姓名,顯然這沒有意義。
現在回答什麼時候使用static修飾成員方法。
我個人的理解很簡單,只要該成員方法不需要與非static的成員打交道,就可以使用static。換句話說,只要該方法的執行與物件本身的狀態沒有關係,就可以使用static(這個結論可能過於草率)。這類方法通常只對傳入的引數作處理,執行過程和自身狀態毫無關係,比如我們熟知的Integer和String。
Integer.toBinaryString(10);
String.valueOf(12);
Integer和String雖然都有非static的成員,但是這兩個方法都不與非static的成員打交道,所以可以定義成static的。
通常,我們在定義一個工具類時,一般把它的方法定義成static的,因為這種類只用作工具,只關注他的行為,不關注他的狀態,所以不需要定義成員變數。使用這種工具類的方法時無需建立物件,既簡單又節省資源。建立物件來呼叫反而麻煩且浪費資源,所以這種類被設計出來後就乾脆不允許建立物件,因為其構造方法被設計成private許可權了。比如我們用的Math和Arrays,還有Collections。這三個類時我們java中最常見的三個工具類。
static在實際開發中有很多巧妙的用法,只有理解了static的意義,我們才能領略其中的巧妙。