在《Java編程思想》P86頁有這樣一段話:面試
static方法就是沒有this的方法。在static方法內部不能調用非靜態方法,反過來是能夠的。並且能夠在沒有建立任何對象的前提下,僅僅經過類自己來調用static方法。這實際上正是static方法的主要用途。
簡而言之,一句話來描述就是:方便在沒有建立對象的狀況下來進行調用(方法/變量)。
static
能夠用來修飾類的成員方法、類的成員變量,另外能夠編寫static代碼塊來優化程序性能。編程
static方法
static方法通常稱做靜態方法,因爲靜態方法不依賴於任何對象就能夠進行訪問,所以對於靜態方法來講,是沒有this的, 由於它不依附於任何對象,既然都沒有對象,就談不上this了。
而且因爲這個特性,在靜態方法中不能訪問類的非靜態成員變量和非靜態成員方法,由於非靜態成員方法/變量都是必須依賴具體的對象纔可以被調用。性能
static變量
static變量也稱做靜態變量,靜態變量和非靜態變量的區別是:優化
static成員變量的初始化順序按照定義的順序進行初始化。this
static代碼塊
static關鍵字還有一個比較關鍵的做用就是 用來造成靜態代碼塊以優化程序性能。code
static塊能夠置於類中的任何地方,類中能夠有多個static塊。在類初次被加載的時候,會按照static塊的順序來執行每一個static塊,而且只會執行一次。對象
爲何說static塊能夠用來優化程序性能,是由於它的特性:只會在類加載的時候執行一次。下面看個例子:繼承
public boolean isBornBoomer() { Date startDate = Date.valueOf("1946"); Date endDate = Date.valueOf("1964"); return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0; }
isBornBoomer是用來這我的是不是1946-1964年出生的,而每次isBornBoomer被調用的時候,都會生成startDate和endDate兩個對象,形成了空間浪費。
若是改爲這樣效率會更好:內存
private static Date startDate,endDate; static{ startDate = Date.valueOf("1946"); endDate = Date.valueOf("1964"); }
所以,不少時候會將一些只須要進行一次的初始化操做都放在static代碼塊中進行。class
下面這段代碼的輸出結果是什麼?
public class Test extends Base{ static{ System.out.println("test static"); } public Test(){ System.out.println("test constructor"); } public static void main(String[] args) { new Test(); } } class Base{ static{ System.out.println("base static"); } public Base(){ System.out.println("base constructor"); } }
結果:
base static
test static
base constructor
test constructor
在執行開始,先要尋找到main方法,由於main方法是程序的入口,可是在執行main方法以前,必須先加載Test類。而在加載Test類的時候發現Test類繼承自Base類,所以會轉去先加載Base類,在加載Base類的時候,發現有static塊,便執行了static塊。在Base類加載完成以後,便繼續加載Test類,而後發現Test類中也有static塊,便執行static塊。在加載完所需的類以後,便開始執行main方法。在main方法中執行new Test()的時候會先調用父類的構造器,而後再調用自身的構造器。