詳解Java關(guān)鍵字final
一、常見問題
- 所有的final修飾的字段都是編譯期常量嗎?
- 如何理解private所修飾的方法是隱式的final?
- 說說final類型的類如何拓展?比如String是final類型,我們想寫個MyString復(fù)用所有String中方法,同時增加一個新的toMyString()的方法,應(yīng)該如何做?
- final方法可以被重載嗎?可以
- 父類的final方法能不能夠被子類重寫?不可以
- 說說final域重排序規(guī)則?
- 說說final的原理?
- 使用 final 的限制條件和局限性?
二、final修飾類
當某個類的整體定義為final時,就表明了你不能打算繼承該類,而且也不允許別人這么做。即這個類是不能有子類的。
注意:final類中的所有方法都隱式為final,因為無法覆蓋他們,所以在final類中給任何方法添加final關(guān)鍵字是沒有任何意義的。
三、final修飾方法
類中所有private方法都隱式地指定為final的,由于無法取用private方法,所以也就不能覆蓋它??梢詫rivate方法增添final關(guān)鍵字,但這樣做并沒有什么好處。
public class Base {
private void test() {
}
}
public class Son extends Base{
public void test() {
}
public static void main(String[] args) {
Son son = new Son();
Base father = son;
//father.test();
}
}
Base和Son都有方法test(),但是這并不是一種覆蓋,因為private所修飾的方法是隱式的final,也就是無法被繼承,所以更不用說是覆蓋了,在Son中的test()方法不過是屬于Son的新成員罷了,Son進行向上轉(zhuǎn)型得到father,但是father.test()是不可執(zhí)行的,因為Base中的test方法是private的,無法被訪問到。
四、final方法是可以被重載的
我們知道父類的final方法是不能夠被子類重寫的,那么final方法可以被重載嗎? 答案是可以的,下面代碼是正確的。
public class FinalExampleParent {
public final void test() {
}
public final void test(String str) {
}
}
修飾參數(shù)
Java允許在參數(shù)列表中以聲明的方式將參數(shù)指明為final,這意味這你無法在方法中更改參數(shù)引用所指向的對象。這個特性主要用來向匿名內(nèi)部類傳遞數(shù)據(jù)。
五、修飾變量
public class Test {
//編譯期常量
final int i = 1;
final static int J = 1;
final int[] a = {1,2,3,4};
//非編譯期常量
Random r = new Random();
final int k = r.nextInt();
public static void main(String[] args) {
}
}
k的值由隨機數(shù)對象決定,所以不是所有的final修飾的字段都是編譯期常量,只是k的值在被初始化后無法被更改。
六、static final
一個既是static又是final 的字段只占據(jù)一段不能改變的存儲空間,它必須在定義的時候進行賦值,否則編譯器將不予通過。
public class finaltest
{
//Random對象r
static Random r = new Random();
//生成隨機數(shù)k
final int k = r.nextInt(10);
//生成隨機數(shù)k2
static final int k2 = r.nextInt(10);
public static void main(String[] args) {
finaltest t1 = new finaltest();
System.out.println("k="+t1.k+" k2="+t1.k2);
finaltest t2 = new finaltest();
System.out.println("k="+t2.k+" k2="+t2.k2);
}
}
k=2 k2=7
k=8 k2=7
我們可以發(fā)現(xiàn)對于不同的對象k的值是不同的,但是k2的值卻是相同的,這是為什么呢? 因為static關(guān)鍵字所修飾的字段并不屬于一個對象,而是屬于這個類的。也可簡單的理解為static final所修飾的字段僅占據(jù)內(nèi)存的一個一份空間,一旦被初始化之后便不會被更改。
七、black final
Java允許生成空白final,也就是說被聲明為final但又沒有給出定值的字段,但是必須在該字段被使用之前被賦值,這給予我們兩種選擇:
- 在定義處進行賦值(這不叫空白final)
- 在構(gòu)造器中進行賦值,保證了該值在被使用前賦值。
這增強了final的靈活性。
final int i1 = 1;
final int i2;//空白final
public finaltest() {
i2 = 1;
}
public finaltest(int x) {
this.i2 = x;
}
可以看到i2的賦值更為靈活。但是請注意,如果字段由static和final修飾,僅能在定義處賦值,因為該字段不屬于對象,屬于這個類。
八、final域重排序規(guī)則
上面我們聊的final使用,應(yīng)該屬于Java基礎(chǔ)層面的,當理解這些后我們就真的算是掌握了final嗎? 有考慮過final在多線程并發(fā)的情況嗎? 在java內(nèi)存模型中我們知道java內(nèi)存模型為了能讓處理器和編譯器底層發(fā)揮他們的最大優(yōu)勢,對底層的約束就很少,也就是說針對底層來說java內(nèi)存模型就是一弱內(nèi)存數(shù)據(jù)模型。同時,處理器和編譯為了性能優(yōu)化會對指令序列有編譯器和處理器重排序。那么,在多線程情況下,final會進行怎樣的重排序? 會導(dǎo)致線程安全的問題嗎? 下面,就來看看final的重排序。
到此這篇關(guān)于詳解Java關(guān)鍵字final的文章就介紹到這了,更多相關(guān)Java關(guān)鍵字final內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決IDEA2020.2插件lombok報錯問題(親測有效)
這篇文章主要介紹了解決IDEA2020.2插件lombok報錯問題,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08
Java畢業(yè)設(shè)計實戰(zhàn)之工作管理系統(tǒng)的實現(xiàn)
這是一個使用了java+SSM+Jsp+Mysql開發(fā)的工作干活管理系統(tǒng),是一個畢業(yè)設(shè)計的實戰(zhàn)練習(xí),具有管理系統(tǒng)該有的所有功能,感興趣的朋友快來看看吧2022-02-02
springboot中在非bean類中調(diào)用bean的實現(xiàn)方法
在Spring Boot中,非Bean類調(diào)用Bean方法通常需要通過靜態(tài)方法獲取Bean實例,然后調(diào)用相應(yīng)的方法,這種方法避免了直接在非Bean類中注入Bean,保持了代碼的簡潔和可維護性,通過這種方式,可以在不改變原有代碼結(jié)構(gòu)的情況下,實現(xiàn)Bean方法的調(diào)用2025-02-02
Springboot并發(fā)調(diào)優(yōu)之大事務(wù)和長連接
這篇文章主要介紹了Springboot并發(fā)調(diào)優(yōu)之大事務(wù)和長連接,重點分享長事務(wù)以及長連接導(dǎo)致的并發(fā)排查和優(yōu)化思路和示例,具有一定的參考價值,感興趣的可以了解一下2022-05-05
基于UncategorizedSQLException異常處理方案
這篇文章主要介紹了基于UncategorizedSQLException異常處理方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12

