Java基础篇:final关键字
final表示的是“無法被改變的”,不想被改變的理由有兩種,一種是效率,一種是設計。使用到final的一般有四種情況:變量、方法、類、參數。
?
一、final變量:
有時候變量的恒定不變是很有用的,它能夠減輕系統運行時的負擔。對于這些恒定不變的數據我可以叫做“常量”。“常量”主要應用與以下兩個地方:
(1)編譯期常量:永遠不可改變。
(2)運行時常量:運行期初始化時,我們希望它不會被改變。
對于編譯期常量,它在類加載的過程就已經完成了初始化,所以當類加載完成后是不可更改的,編譯期可以將它代入到任何用到它的計算式中,也就是說可以在編譯期執行計算式。當然對于編譯期常量,只能使用基本類型,而且必須要在定義時進行初始化。
有些變量,我們希望它可以根據對象的不同而表現不同,但同時又不希望它被改變,這個時候我們就可以使用運行期常量。對于運行期常量,它既可是基本數據類型,也可以是引用數據類型。基本數據類型不可變的是其內容,而對于對象引用,不能改變的是他的引用,而對象本身是可以修改的。因為引用類型變量里面放的是個地址,所以用final修飾引用類型變量指的是它里面的地址不能變,并不是說這個地址所指向的對象或數組的內容不可以變:
? ? ? 例如:類中有一個屬性是final Person p=new Person("name");?那么你不能對p進行重新賦值,但是可以改變p里面屬性的值,p.setName('newName');
? ? ? ?final修飾屬性,聲明成員變量時可以不賦值,而且一旦賦值就不能被修改了。對final屬性可以在三個地方賦值:聲明時、初始化塊中、構造方法中。總之一定要賦值。 (如果修飾的是類變量:必須要在靜態初始化塊中指定初始值或者聲明該類變量時指定初始值,而且只能在這兩個地方之一進行指定;如果聲明的是局部變量:如果final局部變量未進行初始化,可以進行賦值,當且僅有一次賦值,一旦賦值之后再次賦值就會出錯)
?
二、final方法:
當父類的方法被final修飾時,子類不能重寫父類的該方法,但可以被子類繼承或者重載。所以finali方法使用的第一個原因就是方法鎖定。比如在Object中,getClass()方法就是final的,我們就不能重寫該方法,但是hashCode()方法就不是被final所修飾的,我們就可以重寫hashCode()方法。
第二個原因就是效率問題:在《Java編程思想》中,在java的早期實現中,如果將一個方法指明為final,就是同意編譯器將針對該方法的所有調用都轉為內嵌調用。當編譯器發現一個final方法的調用命令時,它會根據自己的謹慎判斷,跳過插入程序代碼這種正常的調用方式而執行方法調用機制(將參數壓入棧,跳至方法代碼處執行,然后跳回并清理棧中的參數,處理返回值),并且以方法體中的實際代碼的副本來代替方法調用。這將消除方法調用的開銷。當然,如果一個方法很大,你的程序代碼會膨脹,因而可能看不到內嵌所帶來的性能上的提高,因為所帶來的性能會花費于方法內的時間量而被縮減。
通俗一點說就是:當一個方法被修飾為final方法時,意味著編譯器可能將該方法用內聯(inline)方式載入,所謂內聯方式,是指編譯器不用像平常調用函數那樣的方式來調用方法,而是直接將方法內的代碼通過一定的修改后copy到原代碼中。這樣可以讓代碼執行的更快(因為省略了調用函數的開銷)。inline需要在編譯的時候就知道最后要用哪個函數, 顯然,非final是不行的。非final方法可能在子類中被重寫,由于可能出現多態的情況,編譯器在編譯階段,并不能確定將來調用方法的對象的真正類型,也就無法確定到底調用哪個方法。
注意:
- 父類的final方法是不能被子類所重寫的,也就是說子類是不能夠存在和父類一模一樣的方法的;
- 父類的private成員方法是不能被子類方法覆蓋的,因此private類型的方法默認是final類型的。
- final不能用于修飾構造方法。?
?
三、final類:
final類不能被繼承,沒有子類,final類中所有方法都是final的。子類繼承往往可以重寫父類的方法和改變父類屬性,會帶來一定的安全隱患,因此,當一個類不希望被繼承時就可以使用final修飾。對于final修飾的類來說,它的成員變量可以為final,也可以為非final。如果定義為final,那么final數據的規則同樣適合它,而它的方法則會自動的加上final,因為final類是無法被繼承,所以這個是默認的。
?
四、final參數:
?在實際應用中,我們除了可以用final修飾成員變量、成員方法、類,還可以修飾參數、若某個參數被final修飾了,則代表了該參數是不可改變的。final修飾參數在內部類中是非常有用的,在匿名內部類中,為了保持參數的一致性,若所在的方法的形參需要被內部類里面使用時,該形參必須為final。
如果在方法中我們修改了該參數,則編譯器會提示你:The final local variable i cannot be assigned. It must be blank and not using a compound assignment。
public class Custom {public void test(final int i){//i++; ---final參數不可改變System.out.println(i);}public void test(final Person p){//p = new Person(); --final參數不可變p.setName("test");} }?
小結:
?
final成員變量表示常量,只能被賦值一次,賦值后值不能再改變。?
final方法不能被子類的方法覆蓋,但可以被繼承。
final類不能被繼承,沒有子類,final類中的方法默認是final的。?
?
總結
以上是生活随笔為你收集整理的Java基础篇:final关键字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java基础篇:String、Strin
- 下一篇: Java基础篇:异常机制