www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > > 架構(gòu)師社區(qū)
[導(dǎo)讀]今天來(lái)聊 final 關(guān)鍵字,因?yàn)樽罱诳吹膸妆緯?shū)都講到了 final 關(guān)鍵字,發(fā)現(xiàn)好多小細(xì)節(jié)自己都忽視了,抽空總結(jié)了一下,分享給大家。

前言

大家好,我是狂聊君。

今天來(lái)聊 final 關(guān)鍵字,因?yàn)樽罱诳吹膸妆緯?shū)都講到了 final 關(guān)鍵字,發(fā)現(xiàn)好多小細(xì)節(jié)自己都忽視了,抽空總結(jié)了一下,分享給大家。

正文

final關(guān)鍵字是一個(gè)常用的關(guān)鍵字,可以修飾變量、方法、類(lèi),用來(lái)表示它修飾的類(lèi)、方法和變量不可改變,下面就聊一下使用 final 關(guān)鍵字的一些小細(xì)節(jié)。

細(xì)節(jié)一、final 修飾類(lèi)成員變量和實(shí)例成員變量的賦值時(shí)機(jī)

對(duì)于類(lèi)變量:

  1. 聲明變量的時(shí)候直接賦初始值
  2. 在靜態(tài)代碼塊中給類(lèi)變量賦初始值

如下代碼所示:

public class FinalTest { //a變量直接賦值 private final static int a = 1; private final static int b; //b變量通過(guò)靜態(tài)代碼塊賦值 static {
        b=2;
    }}

對(duì)于實(shí)例變量:

  1. 在聲明變量的時(shí)候直接賦值
  2. 在非靜態(tài)代碼塊中賦值
  3. 在構(gòu)造器中賦初始化值

如下代碼所示:

public class FinalTest { //c變量在在聲明時(shí)直接賦值 private final int c =1; private final int d; private final int e; //d變量在非靜態(tài)代碼塊中賦值 {
        d=2;
    } //e變量在構(gòu)造器中賦值 FinalTest(){
        e=3;
    }
}

細(xì)節(jié)二、當(dāng) final 修飾的成員變量未對(duì)它進(jìn)行初始化時(shí),會(huì)出現(xiàn)錯(cuò)誤嗎?

答:會(huì)出現(xiàn)錯(cuò)誤。因?yàn)?java 語(yǔ)法規(guī)定,final 修飾的成員變量必須由程序員顯示的初始化,系統(tǒng)不會(huì)對(duì)變量進(jìn)行隱式的初始化。

如下圖所示,未初始變量就會(huì)出現(xiàn)編譯錯(cuò)誤:


final關(guān)鍵字的這8個(gè)小細(xì)節(jié),你get到幾個(gè)?


細(xì)節(jié)三、final 修飾基本類(lèi)型變量和引用類(lèi)型變量的區(qū)別

如果 fianl 修飾的是一個(gè)基本數(shù)據(jù)類(lèi)型的數(shù)據(jù),一旦賦值后就不能再次更改。

那么 final 修飾的是引用數(shù)據(jù)類(lèi)型呢?這個(gè)引用的變量能夠改變嗎?

看下面的代碼:

public class FinalTest { //在聲明final實(shí)例成員變量時(shí)進(jìn)行賦值 private final static Student student = new Student(50, "Java"); public static void main(String[] args) { //對(duì)final引用數(shù)據(jù)類(lèi)型student進(jìn)行更改 student.age = 100;
        System.out.println(student.toString());
    } static class Student { private int age; private String name; public Student(int age, String name) { this.age = age; this.name = name;
        } @Override public String toString() { return "Student{" + "age=" + age + ", name='" + name + '\'' + '}';
        }
    }
} //下面是打印結(jié)果 Student{age=100, name='Java'}

從打印結(jié)果可以看到:引用數(shù)據(jù)類(lèi)型變量 student 的 age 屬性修改成 100,是可以修改成功的。

結(jié)論:

  1. 當(dāng) final 修飾基本數(shù)據(jù)類(lèi)型變量時(shí),不能對(duì)基本數(shù)據(jù)類(lèi)型變量重新賦值,因此基本數(shù)據(jù)類(lèi)型變量不能被改變。
  2. 對(duì)于引用類(lèi)型變量而言,它僅僅保存的是一個(gè)引用,final 只保證這個(gè)引用類(lèi)型變量所引用的地址不會(huì)發(fā)生改變,即一直引用這個(gè)對(duì)象,但這個(gè)對(duì)象里面的屬性是可以改變的。

細(xì)節(jié)四、final 修飾局部變量的場(chǎng)景

fianl 局部變量由程序員進(jìn)行顯示的初始化,如果 final 局部變量進(jìn)行初始化之后就不能再次進(jìn)行更改。

如果 final 變量未進(jìn)行初始化,可以進(jìn)行賦值,并且只能進(jìn)行一次賦值,一旦賦值之后再次賦值就會(huì)出錯(cuò)。

下面的代碼演示 final 修飾局部變量的情況:

final關(guān)鍵字的這8個(gè)小細(xì)節(jié),你get到幾個(gè)?

細(xì)節(jié)五、final 修飾方法會(huì)對(duì)重載有影響嗎?重寫(xiě)呢?

對(duì)于重載:final 修飾方法后是可以重載的

如下代碼:

public class FinalTest { public final void test(){

    } //重載方法不會(huì)出現(xiàn)問(wèn)題 public final void test(String test){

    }
}

對(duì)于重寫(xiě):當(dāng)父類(lèi)的方法被 final 修飾的時(shí)候,子類(lèi)不能重寫(xiě)父類(lèi)的該方法

final關(guān)鍵字的這8個(gè)小細(xì)節(jié),你get到幾個(gè)?

如上代碼所示,可以看到會(huì)出現(xiàn) cannot override ,overridden method is final 的編譯錯(cuò)誤提示

細(xì)節(jié)六、final 修飾類(lèi)的場(chǎng)景

當(dāng)用final修飾一個(gè)類(lèi)時(shí),表明這個(gè)類(lèi)不能被繼承。也就是說(shuō),如果一個(gè)類(lèi)你永遠(yuǎn)不會(huì)讓他被繼承,就可以用 final 進(jìn)行修飾。

final 類(lèi)中的成員變量可以根據(jù)需要設(shè)為 final,但是要注意 final 類(lèi)中的所有成員方法都會(huì)被隱式地指定為 final 方法。

細(xì)節(jié)七、寫(xiě) final 域的重排序規(guī)則,你知道嗎?

這個(gè)規(guī)則是指禁止對(duì) final 域的寫(xiě)重排序到構(gòu)造函數(shù)之外,這個(gè)規(guī)則的實(shí)現(xiàn)主要包含了兩個(gè)方面:

  1. JMM 禁止編譯器把 final 域的寫(xiě)重排序 到 構(gòu)造函數(shù) 之外
  2. 編譯器會(huì)在 final 域?qū)懼螅瑯?gòu)造函數(shù) return 之前,插入一個(gè) StoreStore 屏障。這個(gè)屏障可以禁止處理器把 final 域的寫(xiě)重排序到構(gòu)造函數(shù)之外

給舉個(gè)例子,要不太抽象了,先看一段代碼

public class FinalTest{ private int a; //普通域 private final int b; //final域 private static FinalTest finalTest; public FinalTest() {
        a = 1; // 1. 寫(xiě)普通域 b = 2; // 2. 寫(xiě)final域 } public static void writer() {
        finalTest = new FinalTest();
    } public static void reader() {
        FinalTest demo = finalTest; // 3.讀對(duì)象引用 int a = demo.a; //4.讀普通域 int b = demo.b; //5.讀final域 }
}

假設(shè)線(xiàn)程 A 在執(zhí)行 writer()方法,線(xiàn)程 B 執(zhí)行 reader()方法。

由于變量 a 和變量 b 之間沒(méi)有依賴(lài)性,所以就有可能會(huì)出現(xiàn)下圖所示的重排序

final關(guān)鍵字的這8個(gè)小細(xì)節(jié),你get到幾個(gè)?

由于普通變量 a 可能會(huì)被重排序到構(gòu)造函數(shù)之外,所以線(xiàn)程 B 就有可能讀到的是普通變量 a 初始化之前的值(零值),這樣就可能出現(xiàn)錯(cuò)誤。

而 final 域變量 b,根據(jù)重排序規(guī)則,會(huì)禁止 final 修飾的變量 b 重排序到構(gòu)造函數(shù)之外,從而 b 能夠正確賦值,線(xiàn)程 B 就能夠讀到 final 域變量 b初始化后的值。

結(jié)論:寫(xiě) final 域的重排序規(guī)則可以確保在對(duì)象引用為任意線(xiàn)程可見(jiàn)之前,對(duì)象的 final 域已經(jīng)被正確初始化過(guò)了,而普通域就不具有這個(gè)保障。

細(xì)節(jié)八:讀 final 域的重排序規(guī)則,你知道嗎?

這個(gè)規(guī)則是指在一個(gè)線(xiàn)程中,初次讀對(duì)象引用和初次讀該對(duì)象包含的 final 域,JMM 會(huì)禁止這兩個(gè)操作的重排序。

還是上面那段代碼

public class FinalTest{ private int a; //普通域 private final int b; //final域 private static FinalTest finalTest; public FinalTest() {
        a = 1; // 1. 寫(xiě)普通域 b = 2; // 2. 寫(xiě)final域 } public static void writer() {
        finalTest = new FinalTest();
    } public static void reader() {
        FinalTest demo = finalTest; // 3.讀對(duì)象引用 int a = demo.a; //4.讀普通域 int b = demo.b; //5.讀final域 }
}

假設(shè)線(xiàn)程 A 在執(zhí)行 writer()方法,線(xiàn)程 B 執(zhí)行 reader()方法。

線(xiàn)程 B 可能就會(huì)出現(xiàn)下圖所示的重排序

final關(guān)鍵字的這8個(gè)小細(xì)節(jié),你get到幾個(gè)?

可以看到,由于讀對(duì)象的普通域被重排序到了讀對(duì)象引用的前面,就會(huì)出現(xiàn)線(xiàn)程 B 還未讀到對(duì)象引用就在讀取該對(duì)象的普通域變量,這顯然是錯(cuò)誤的操作。而 final 域的讀操作就“限定”了在讀 final 域變量前已經(jīng)讀到了該對(duì)象的引用,從而就可以避免這種情況。

結(jié)論:讀 final 域的重排序規(guī)則可以確保在讀一個(gè)對(duì)象的 final 域之前,一定會(huì)先讀包含這個(gè) final 域的對(duì)象的引用。

結(jié)束

今天給大家總結(jié)了一下使用 final 關(guān)鍵字容易忽視的一些小細(xì)節(jié),看完希望你能有所收獲。


免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶(hù)體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(chē)(EV)作為新能源汽車(chē)的重要代表,正逐漸成為全球汽車(chē)產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車(chē)的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車(chē)的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車(chē) 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車(chē)場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周?chē)娮釉O(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉