Static與Final
1. Static關鍵字
在Java中並不存在全局變量的概念,但是我們可以通過static來實現一個“偽全局”的概念,在Java中static表示“全局”或者“靜態”的意思,用來修飾成員變量和成員方法,當然也可以修飾代碼塊。
1.1 static變量
按照是否靜態的對類成員變量進行分類可分兩種:一種是被static修飾的變量,叫靜態變量或類變量;另一種是沒有被static修飾的變量,叫實例變量。兩者的區別是:
對於靜態變量在內存中只有一個拷貝(節省內存),JVM只為靜態分配一次內存,在加載類的過程中完成靜態變量的內存分配,可用類名直接訪問(方便),當然也可以通過對象來訪問(但是這是不推薦的)。
對於實例變量,沒創建一個實例,就會為實例變量分配一次內存,實例變量可以在內存中有多個拷貝,互不影響(靈活)。
1.2 靜態方法
靜態方法可以直接通過類名調用,任何的實例也都可以調用,因此靜態方法中不能用this和super關鍵字,不能直接訪問所屬類的實例變量和實例方法(就是不帶static的成員變量和成員成員方法),只能訪問所屬類的靜態成員變量和成員方法。因為實例成員與特定的對象關聯。
因為static方法獨立於任何實例,因此static方法必須被實現,而不能是抽象的abstract。
1.3 static代碼塊
static代碼塊也叫靜態代碼塊,是在類中獨立於類成員的static語句塊,可以有多個,位置可以隨便放,它不在任何的方法體內,JVM加載類時會執行這些靜態的代碼塊,如果static代碼塊有多個,JVM將按照它們在類中出現的先後順序依次執行它們,每個代碼塊只會被執行一次。
無論是變量,方法,還是代碼塊,只要用static修飾,就是在類被加載時就已經”準備好了”,也就是可以被使用或者已經被執行,都可以脫離對象而執行。反之,如果沒有static,則必須要依賴於對象實例。
2. Final關鍵字
在Java中,final關鍵字可以用來修飾類、方法和變量(包括成員變量和局部變量)。
2.1 修飾類
當用final修飾一個類時,表明這個類不能被繼承。final類中的成員變量可以根據需要設為final,但是要註意final類中的所有成員方法都會被隱式地指定為final方法。
在使用final修飾類的時候,要註意謹慎選擇,除非這個類真的在以後不會用來繼承或者出於安全的考慮,盡量不要將類設計為final類。
2.2 修飾方法
下面這段話摘自《Java編程思想》第四版第143頁:
“使用final方法的原因有兩個。第一個原因是把方法鎖定,以防任何繼承類修改它的含義;第二個原因是效率。在早期的Java實現版本中,會將final方法轉為內嵌調用。但是如果方法過於龐大,可能看不到內嵌調用帶來的任何性能提升。在最近的Java版本中,不需要使用final方法進行這些優化了。“
因此,只有在想明確禁止該方法在子類中被覆蓋的情況下,才將方法設置為final的。
註:類的private方法會隱式地被指定為final方法。
2.3 修飾變量(成員變量和局部變量)
修飾變量是final用得最多的地方。
final變量的基本語法:
- 對於一個final變量,如果是基本數據類型的變量,則其數值一旦在初始化之後便不能更改
- 如果是引用類型的變量,則在對其初始化之後便不能再讓其指向另一個對象
2.4 final對程序執行效率的影響
這個在jvm機制中可見到一些影響,但提升程序執行效率首先應該更多的從算法復雜度、業務流程合理性、軟件架構合理性以及後期運行時環境調優上著手,而僅從某種語法內部運行機制上打主意意義不大。但static對程序性能有顯著影響。
Static與Final