最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入淺出的講解Java關(guān)鍵字final的作用

 更新時間:2023年06月06日 11:54:37   作者:alexhilton  
final是Java中非常常見的一個關(guān)鍵字,可以說每天都在使用它,雖然常見,但卻也不見得都那么顯而易見,今天就來研究一下final,以加深對它的理解和更合理的運用,需要的朋友可以參考下

final可以用來干什么

修飾類

當(dāng)一個類不想被繼承時,就可以用final來修飾。

修飾方法

當(dāng)一個方法不想被子類覆寫(Override)時,可以用final來修飾。另外一方面,把方法用final來修飾也有一定的性能提升上的幫助,因為虛擬機知道它不會被覆寫,所以可以以更簡單的方式來處理。

private的方法,默認(rèn)都會被編譯器加上final.

修飾變量

被final修飾的變量只能賦值一次,之后不能再被修改。如:

final int a = 10;
a = 4; // compilation error

需要注意的是,這里說的是只能賦值一次,并不意味著,非要在聲明變量時直接初始化,比如,下面的代碼也是完全合法的:

final int a;
if (foo()) {
    a = 3;
} else {
    a = 4;
}

修飾域變量

域變量也是變量,所以用final來修飾的第一個作用就是賦值后,不能再修改變量的值,比如:

final int a = 10;
final Object b = new Object();

對于基本類型來說,就是變量值不能再被修改;對于引用來說,就是不能再讓其指向其他對象或者null。

但對于域變量,聲明為final的域變量必須在聲明時初始化,或者在構(gòu)造方法中初始化,否則會有編譯錯誤。

此外,聲明為final的域變量還有內(nèi)存模型上的語義,下面詳細(xì)說

內(nèi)存模型的作用--防止變量從構(gòu)造方法中逸出

這個主要是針對被final修飾的域變量,虛擬機會有禁止指令重排的保證:

  • 在構(gòu)造方法內(nèi)對一個final變量的寫入,與隨后這個被構(gòu)造對象的引用賦值給一個引用變量,這二個順序不改變,final變量的寫入一定要早于對象引用的賦值。

什么意思呢?在多線程環(huán)境下,域變量是有可能從構(gòu)造方法中逸出的,也就是說線程有可能讀到還沒有被構(gòu)造方法初始化的域變量的值。比如:

class Foo {
    int a;
    Foo(int v) {
        a = v;
    }
}

如果是在多線程環(huán)境下,一個線程A在創(chuàng)建Foo的對象,另一個線程B在讀對象的a的值,則B是有可能讀到未正確初始化a的值(默認(rèn)初始值0)。這就是域變量從構(gòu)造方法中逸出。

關(guān)鍵字final可以禁止虛擬機指令重排,從而保證了構(gòu)造方法執(zhí)行完畢前final修飾的變量一定是初始化過了的。

匿名內(nèi)部類使用外部變量時為何要強制使用final修飾

這個大家肯定都習(xí)以為常了,比如

private void initViews() {
    final int a = 3; // Compilation error if remove final
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (a > 1) {
                // volala
            }
        }
    }
}

那么,有沒有想過為什么?而像其他支持完整閉包的語言如JavaScript,Python等,是沒有這等限制的。究其原因,是Java對閉包支持不夠完整,或者說它并不是像動態(tài)語言那樣的完整閉包。對于匿名內(nèi)部類來說,編譯器會創(chuàng)建一個命名類(OutClass$1之類的),然后把匿名類所在的能捕獲的變量,以構(gòu)造參數(shù)的形式傳遞給內(nèi)部類使用,這樣一樣,外部的變量與內(nèi)部類看到的變量是不同的,雖然它們的值是相同的,因此,如果再允許外部修改這些變量,或者內(nèi)部類里面修改這些變量,都會造成數(shù)據(jù)的不一致性(因為它們是不同的變量),所以Java強制要求匿名內(nèi)部類訪問的外部變量要加上final來修飾。

對于其他語言,匿名內(nèi)部類,持有的是外部變量的一個包裝的引用(wrapper reference),這可以能看不懂,但是理解起來就是內(nèi)部類能直接訪問外部變量,外部與閉包內(nèi)部訪問的是同一個變量,因此外部修改了,內(nèi)部能看到變化,內(nèi)部修改了,外部也能看到變化。

一句話總結(jié)就是,Java內(nèi)部類與外部持有的是值相同的不同的變量;其他支持閉包的語言則持有的是相同的變量。

建議能使用final的地方就加上final修飾

最后來聊聊,啥時候應(yīng)該用final呢?孤的建議(以及眾多大師的建議)就是能多用就多用,除非不能用final,否則就用。原因,有這么幾條:

  • 域變量盡可能加上final

    這個原因比較明確,前面也提到了,在多線程條件下,會有很大的優(yōu)勢。盡可能加上final來修飾域變量,甚至用Immutable Object,可以省去構(gòu)造時的多線程同步。

    多線程最大的麻煩是狀態(tài)同步,啥是狀態(tài)?其實就是共享數(shù)據(jù),域變量就是共享數(shù)據(jù),所以,如果共享數(shù)據(jù)都是不可變的(Immutable),那么自然就沒有了同步上的麻煩。

  • final類和方法能提升性能

    正常的類和方法,虛擬機需要為了繼承和方法覆寫而做一次準(zhǔn)備,如果加上了final,虛擬機知道它不會被繼承或者覆寫,那么就可以做一些優(yōu)化。雖然,這并不顯著,但是還是可以提升一些性能的。

  • final變量能提升可讀性

    無論是域變量還是本地變量,加上了final修飾,程序的維護(hù)者就知道了,這個變量的值不會再改變,這無疑會大大增加可讀性。

以上就是深入淺出的講解Java關(guān)鍵字final的作用的詳細(xì)內(nèi)容,更多關(guān)于Java 關(guān)鍵字 final的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java處理按鈕點擊事件的方法

    java處理按鈕點擊事件的方法

    下面小編就為大家?guī)硪黄猨ava處理按鈕點擊事件的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • java如何保證多個線程按一定順序執(zhí)行

    java如何保證多個線程按一定順序執(zhí)行

    這篇文章主要介紹了java如何保證多個線程按一定順序執(zhí)行問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Springboot與Maven多環(huán)境配置的解決方案

    Springboot與Maven多環(huán)境配置的解決方案

    多環(huán)境配置的解決方案有很多,我看到不少項目的多環(huán)境配置都是使用Maven來實現(xiàn)的,本文就實現(xiàn)Springboot與Maven多環(huán)境配置,感興趣的可以了解下
    2021-06-06
  • Java參數(shù)校驗中validation和validator的區(qū)別詳解

    Java參數(shù)校驗中validation和validator的區(qū)別詳解

    這篇文章主要介紹了Java參數(shù)校驗中validation和validator的區(qū)別詳解,一般對于復(fù)雜的業(yè)務(wù)參數(shù)校驗,可以通過校驗類單獨的校驗方法進(jìn)行處理,通常對于一些與業(yè)務(wù)無關(guān)簡單的參數(shù)校驗可以采用validation和 validator通過注解的方式實現(xiàn)校驗,需要的朋友可以參考下
    2023-10-10
  • mybatis中xml之trim屬性說明

    mybatis中xml之trim屬性說明

    這篇文章主要介紹了mybatis中xml之trim屬性說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 聊聊Spring循環(huán)依賴三級緩存是否可以減少為二級緩存的情況

    聊聊Spring循環(huán)依賴三級緩存是否可以減少為二級緩存的情況

    這篇文章主要介紹了聊聊Spring循環(huán)依賴三級緩存是否可以減少為二級緩存的情況,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • IDEA2020導(dǎo)入非maven項目并部署tomcat的方法

    IDEA2020導(dǎo)入非maven項目并部署tomcat的方法

    這篇文章主要介紹了IDEA 2020 導(dǎo)入非maven項目并部署tomcat的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • springboot開啟Bean數(shù)據(jù)校驗功能

    springboot開啟Bean數(shù)據(jù)校驗功能

    這篇文章主要介紹了springboot開啟Bean數(shù)據(jù)校驗功能,通過啟用Bean屬性校驗導(dǎo)入JSR303與Hibernate校驗框架坐標(biāo),使用@Validated注解啟用校驗功能,需要的朋友可以參考下
    2023-10-10
  • 超簡單的java獲取鼠標(biāo)點擊位置坐標(biāo)的實例(鼠標(biāo)在Jframe上的坐標(biāo))

    超簡單的java獲取鼠標(biāo)點擊位置坐標(biāo)的實例(鼠標(biāo)在Jframe上的坐標(biāo))

    在Java窗體Jframe上獲取鼠標(biāo)點擊的坐標(biāo),其中使用了匿名內(nèi)部類,實例代碼非常簡單易懂,大家可以學(xué)習(xí)一下
    2018-03-03
  • 通過Maven下載依賴Jar包的流程分享

    通過Maven下載依賴Jar包的流程分享

    本文主要介紹了Maven下載依賴Jar包的詳細(xì)流程,包括輸入Maven倉庫的官方地址、搜索依賴Jar包、選擇版本、復(fù)制和粘貼Maven依賴到pom文件中下載依賴Jar包
    2025-02-02

最新評論

隆化县| 赫章县| 当涂县| 年辖:市辖区| 万荣县| 当雄县| 萨迦县| 东丽区| 大姚县| 涿州市| 七台河市| 玉山县| 逊克县| 昌图县| 辛集市| 湟源县| 永年县| 武功县| 固始县| 梁山县| 祥云县| 丰都县| 舞钢市| 沅江市| 江都市| 如皋市| 长宁县| 浦江县| 沂水县| 崇义县| 新竹市| 利川市| 永德县| 响水县| 金寨县| 崇阳县| 潞西市| 大埔区| 灌南县| 安远县| 邹平县|