對于Java中的 final 關(guān)鍵字,我們首先可以從字面意思上去理解次哈,百度翻譯顯示如下:
也就是說 final 英文意思表示是最后的哄辣,不可更改的。那么對應(yīng)在 Java 中也是表達這樣的意思忧额,可以用 final 關(guān)鍵字修飾變量、方法和類愧口。不管是用來修飾什么睦番,其本意都是指 “它是無法更改的”,這是我們需要牢記的,為什么要無法更改托嚣?無非就是設(shè)計所需或者能提高效率巩检,與前面介紹 static 關(guān)鍵字需要記住其與對象無關(guān)的理念一樣,牢記 final 的不可變的設(shè)計理念后再來了解 final 關(guān)鍵字的用法示启,便會順其自然了兢哭。
1、修飾變量
稍微有點Java基礎(chǔ)的都知道用final關(guān)鍵字修飾的變量稱為常量丑搔,常量的意思是不可更改。變量為基本數(shù)據(jù)類型提揍,不可更改很容易理解啤月,那么對于引用類型呢?不可能改的是其引用地址劳跃,還是對象的內(nèi)容谎仲?
我們首先構(gòu)造一個實體類:Person
package com.ys.bean;
/**
* Create by YSOcean
*/
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
接著根據(jù)創(chuàng)建一個 Person 對象:
可以看到,首先通過 final 關(guān)鍵字修飾一個對象 p刨仑,然后接著將 p 對象指向另一個新的對象郑诺,發(fā)現(xiàn)報錯,也就是說final修飾的引用類型是不能改變其引用地址的杉武。
接著我們改動 p 對象的 name 屬性:
發(fā)現(xiàn)程序沒有報錯辙诞。
結(jié)論:被 final 修飾的變量不可更改其引用地址,但是可以更改其內(nèi)部屬性轻抱。
2飞涂、修飾方法
final 關(guān)鍵字修飾的方法不可被覆蓋。
在《Java編程思想》第 4 版 7.8.2 章節(jié) final 方法p176 頁這樣描述:使用 final 方法原因有兩個:
①祈搜、第一個原因是把方法鎖定较店,以防止任何繼承類修改它的含義,這是出于設(shè)計的考慮:想要確保在繼承中使方法的行為保持不變容燕,并且不會被覆蓋梁呈。
②、第二個原因是效率蘸秘,在 Java 的早期實現(xiàn)中官卡,如果將一個方法聲明為 final,就是同意編譯器將針對該方法的所有調(diào)用都轉(zhuǎn)為內(nèi)嵌調(diào)用醋虏,內(nèi)嵌調(diào)用能夠提高方法調(diào)用效率味抖,但是如果方法很大,內(nèi)嵌調(diào)用不會提高性能灰粮。而在目前的Java版本中(JDK1.5以后)仔涩,虛擬機可以自動進行優(yōu)化了,而不需要使用 final 方法粘舟。
所以final 關(guān)鍵字只有明確禁止覆蓋方法時熔脂,才使用其修飾方法佩研。
PS:《Java編程思想》中指出類中所有的 private 方法都隱式指定為 final 的,所以對于 private 方法霞揉,我們顯式的聲明 final 并沒有什么效果旬薯。但是我們創(chuàng)建一個父類,并在父類中聲明一個 private 方法适秩,其子類中是能夠重寫其父類的private 方法的绊序,這是為什么呢?
父類:Parent.class
package com.ys.bean;
/** * Create by YSOcean */
public class Parent { private void say(){
System.out.println("parent");
}
}
子類:Son.class
package com.ys.bean;
/**
* Create by YSOcean
*/
public class Son extends Parent {
private void say(){
System.out.println("son");
}
}
其實仔細看看秽荞,這種寫法是方法的覆蓋嗎骤公?我們通過多態(tài)的形式并不能調(diào)用到父類的 say() 方法:
并且,如果我們在子類的 say() 方法中扬跋,添加 @Override 注解也是會報錯的阶捆。
所以這種形式并不算方法的覆蓋。
3钦听、修飾類
final 修飾類表示該類不可被繼承洒试。
也就是說不希望某個類有子類的時候,用final 關(guān)鍵字來修飾朴上。并且由于是用 final 修飾的類垒棋,其類中所有的方法也被隱式的指為 final 方法。
在 JDK 中有個最明顯的類 String 痪宰,就是用 final 修飾的捕犬,將 String 類用 final 修飾很重要的一個原因是常量池。關(guān)于 String 類的描述酵镜,可以參考我的這篇博客碉碉。