關(guān)鍵字:
final finalize finally
throws和throw
static關(guān)鍵字的作用
abstract和 interface
super和 this
synchronize和 volatile
1. final finalize finally對(duì)比
(1)性質(zhì)不同
final為關(guān)鍵字笔呀;
finalize為方法刘离;
finally為為區(qū)塊標(biāo)志褪尝,用于try語(yǔ)句中;
(2)作用不同
final:用于標(biāo)識(shí)常量的關(guān)鍵字敛瓷,final標(biāo)識(shí)的關(guān)鍵字存儲(chǔ)在常量池中(在這里final常量的具體用法將在下面進(jìn)行介紹);final定義的變量值不可變斑匪,方法不可覆寫(xiě)呐籽,類不可繼承。
定義變量:一旦初始化(聲明處或構(gòu)造函數(shù)中)便不可改變蚀瘸。對(duì)基本類型是其值不可變狡蝶,對(duì)引用類型是引用不可變;(String天生就是final的)
定義方法:1)使用final定義的方法贮勃,不允許覆寫(xiě)贪惹,認(rèn)為其功能滿足要求無(wú)需擴(kuò)展時(shí);2)允許編譯器將所有對(duì)此方法的調(diào)用轉(zhuǎn)化為inline(行內(nèi)機(jī)制)寂嘉,即可以將此方法直接復(fù)制在調(diào)用處奏瞬,而不是進(jìn)行例行的方法調(diào)用(保存斷點(diǎn)枫绅、壓棧),可以提高效率丝格。但如果過(guò)多的話撑瞧,會(huì)造成代碼膨脹,反而會(huì)影響效率显蝌,慎用预伺。
定義類:無(wú)法被繼承,這也就意味著此類在一個(gè)繼承樹(shù)中是一個(gè)葉子類曼尊;類成員是不是final都可以酬诀。
finalize:方法在Object中進(jìn)行了定義,用于在對(duì)象“消失”時(shí)骆撇,由JVM進(jìn)行調(diào)用用于對(duì)對(duì)象進(jìn)行垃圾回收瞒御,類似于C++中的析構(gòu)函數(shù);用戶自定義時(shí)神郊,用于釋放對(duì)象占用的資源(比如進(jìn)行I/0操作)肴裙;
finally{}:用于標(biāo)識(shí)代碼塊,與try{}進(jìn)行配合涌乳,是異常處理模型的補(bǔ)充蜻懦,不論try中的代碼執(zhí)行完或沒(méi)有執(zhí)行完(這里指有異常),該代碼塊之中的程序必定會(huì)進(jìn)行夕晓;不可單獨(dú)使用宛乃,在一個(gè)try...catch...finally語(yǔ)句塊中最多只有一個(gè)finally;一般用來(lái)維護(hù)對(duì)象的內(nèi)部狀態(tài)蒸辆,清理非內(nèi)存資源征炼。
2. throws和throw對(duì)比
(1)使用位置不同
throw位于方法體內(nèi)部,可以作為單獨(dú)語(yǔ)句使用躬贡;
throws位于方法頭部的參數(shù)列表后面谆奥,不能單獨(dú)使用;
(2)內(nèi)容不同
throw拋出一個(gè)具體的異常對(duì)象拂玻,而且只能是一個(gè)酸些;
throws聲明拋出的異常類,可以同時(shí)聲明多個(gè)纺讲;
(3)作用不同
throw用于在程序中拋出異常擂仍,一旦執(zhí)行說(shuō)明一定有異常拋出,由方法體內(nèi)部語(yǔ)句處理異常熬甚;
throws用于聲明在該方法內(nèi)可能拋出的異常類逢渔,如果拋出了異常,由該方法的調(diào)用者處理乡括,層層上拋肃廓;
總結(jié):函數(shù)調(diào)用時(shí)智厌,如果需要向上層拋出異常,就必須在函數(shù)頭部顯式地聲明(throws Exception1, Exception2)異常類型盲赊;如果僅需要在方法體內(nèi)部處理異常铣鹏,方法體內(nèi)部可自行處理該異常,thorw拋出具體的異常實(shí)例(catch(Exception1 e){...})哀蘑。
3. static關(guān)鍵字的作用
static關(guān)鍵字可用來(lái)修飾屬性诚卸、方法、代碼塊绘迁,目的是把對(duì)象相關(guān)的變成類相關(guān)的合溺,即:不加static的成員是對(duì)象相關(guān)的,歸單個(gè)對(duì)象所有缀台;加static修飾的成員是類成員棠赛,可以通過(guò)類名直接調(diào)用,歸所有對(duì)象所有膛腐。
static修飾的成員變量和成員方法習(xí)慣上稱為靜態(tài)變量和靜態(tài)方法睛约,可以直接通過(guò)類名來(lái)訪問(wèn),訪問(wèn)語(yǔ)法為:
類名.靜態(tài)方法名(參數(shù)列表…)
類名.靜態(tài)變量名
(1)static修飾屬性(類變量哲身、靜態(tài)變量)
被static修飾的變量辩涝,叫靜態(tài)變量或類變量,可通過(guò)類名直接訪問(wèn)律罢;沒(méi)有被static修飾的變量膀值,叫實(shí)例變量棍丐。
靜態(tài)變量為本類所有對(duì)象共享误辑;實(shí)例變量只屬于單個(gè)對(duì)象。
靜態(tài)變量在內(nèi)存中只有一個(gè)拷貝歌逢,在類加載時(shí)被創(chuàng)建和初始化巾钉,JVM只為其分配一次內(nèi)存(節(jié)省內(nèi)存)。類加載過(guò)程只進(jìn)行一次秘案,因此靜態(tài)變量也只會(huì)被創(chuàng)建一次砰苍;實(shí)例變量在創(chuàng)建對(duì)象時(shí)被初始化,在內(nèi)存中有多個(gè)拷貝阱高,每創(chuàng)建一個(gè)對(duì)象就會(huì)為其分配一次內(nèi)存赚导,各實(shí)例變量間互不影響(靈活)。
所以一般在需要實(shí)現(xiàn)以下兩個(gè)功能時(shí)使用靜態(tài)變量:
1).在對(duì)象之間共享值時(shí)赤惊;2).方便訪問(wèn)變量時(shí)
(2)static修飾方法(靜態(tài)方法)
static修飾的方法吼旧,叫靜態(tài)方法,可通過(guò)類名直接訪問(wèn)未舟,為本類所有對(duì)象共享圈暗;
靜態(tài)方法不能訪問(wèn)本類的非靜態(tài)成員(包括實(shí)例變量和方法掂为,因?yàn)榉庆o態(tài)則和特定的對(duì)象關(guān)聯(lián),就不能全類共享了)员串,但是非靜態(tài)方法可以訪問(wèn)靜態(tài)成員(ofcourse勇哗,靜態(tài)成員全類共享);
靜態(tài)方法中不能出現(xiàn)this和super關(guān)鍵字(因?yàn)閠his是指向當(dāng)前對(duì)象寸齐,super.成員名調(diào)用父類成員)欲诺;
因?yàn)閟tatic方法獨(dú)立于任何實(shí)例,因此static方法必須被實(shí)現(xiàn)渺鹦,而不能是抽象的abstract瞧栗;
子類覆蓋父類的靜態(tài)方法時(shí),只能依然覆蓋為靜態(tài)方法(一日static終生static)海铆,但是沒(méi)有多態(tài)迹恐。
Java中main方法必須為static的原因:
在類加載時(shí)無(wú)法創(chuàng)建對(duì)象,而靜態(tài)方法可以不通過(guò)對(duì)象調(diào)用卧斟,所以在類加載時(shí)可以通過(guò)main方法入口運(yùn)行程序殴边。
(3)static修飾代碼塊(初始化塊、靜態(tài)代碼塊)
格式: static{...}
static代碼塊也叫靜態(tài)代碼塊珍语,是在類中獨(dú)立于類成員的static語(yǔ)句塊锤岸,可以有多個(gè),位置可以隨便放板乙,它不在任何的方法體內(nèi)是偷,JVM加載類時(shí)會(huì)執(zhí)行這些靜態(tài)的代碼塊,如果static代碼塊有多個(gè)募逞,JVM將按照它們?cè)陬愔谐霈F(xiàn)的先后順序依次執(zhí)行它們蛋铆,每個(gè)代碼塊只會(huì)被執(zhí)行一次。
初始化總結(jié)(靜態(tài)變量->實(shí)例變量->按聲明初始化->執(zhí)行構(gòu)造方法)
1)首次使用某個(gè)類時(shí)放接,JVM查找相應(yīng)的類文件并加載(Java只有在必要時(shí)才會(huì)逐步載入相應(yīng)的類文件)
首先為所有的靜態(tài)變量分配存儲(chǔ)空間并初始化為默認(rèn)值(全局變量)刺啦,然后按照聲明靜態(tài)變量時(shí)指定的初始化動(dòng)作的順序,以及靜態(tài)初始化塊中的語(yǔ)句在類定義中出現(xiàn)的順序依次執(zhí)行纠脾。這些靜態(tài)的初始化動(dòng)作只會(huì)在其所屬類的類文件加載時(shí)執(zhí)行一次玛瘸。
2)類文件加載完畢后,如果需要?jiǎng)?chuàng)建類的對(duì)象苟蹈,則進(jìn)行如下初始化動(dòng)作
JVM為所有的實(shí)例變量分配足夠的存儲(chǔ)空間并初始化為默認(rèn)值(局部變量)糊渊;然后按聲明實(shí)例變量時(shí)指定初值的初始化動(dòng)作和實(shí)例初始化塊中的語(yǔ)句在類中出現(xiàn)的順序依次執(zhí)行,之后再調(diào)用相應(yīng)的構(gòu)造方法慧脱。
4. abstract和 interface對(duì)比
stract class和interface是支持抽象類定義的兩種機(jī)制渺绒。正是由于這兩種機(jī)制的存在,才賦予了Java強(qiáng)大的面向?qū)ο竽芰Αbstract class和interface之間在對(duì)于抽象類定義的支持方面具有很大的相似性芒篷,區(qū)別:
抽象類(Abstract Class):
(1)只能作為其他類的基類搜变,不能被實(shí)例化(new);
(2)抽象類中的成員是不是abstract無(wú)所謂针炉,并不是必須的挠他。(可以有抽象成員,也可以沒(méi)有任何抽象成員)
(3)抽象類不能同時(shí)是final的篡帕。抽象的總是希望被繼承殖侵,而final類不可被繼承。final和abstract不可同時(shí)存在镰烧。
(4)非抽象類繼承抽象類拢军,必須覆蓋其所有的抽象成員。抽象類繼承抽象類怔鳖,可以不覆蓋所有的抽象成員茉唉。
(5)抽象類允許被聲明
接口(interface):
接口的本質(zhì)是一種特殊的抽象類,用來(lái)描述系統(tǒng)對(duì)外提供的所有服務(wù)结执。
(1)接口中度陆,所有方法都是公開(kāi)、抽象的:public abstract献幔。(都必須被繼承)
(2)接口中懂傀,所有屬性都是公開(kāi)、靜態(tài)蜡感、常量:public static final蹬蚁,且必須賦初值。(所有實(shí)現(xiàn)類共享且不可改變)
接口總是希望被實(shí)現(xiàn)被訪問(wèn)的郑兴,因此所有成員都必須是公開(kāi)的(public)犀斋,確保外界可以訪問(wèn)。接口僅僅描述系統(tǒng)可以做什么杈笔,但不指明如何去做闪水,具體操作由實(shí)現(xiàn)類完成糕非,因此方法都是abstract的蒙具,都必須被繼承;接口不涉及任何的實(shí)現(xiàn)細(xì)節(jié)朽肥,因此無(wú)構(gòu)造方法禁筏,接口不能被實(shí)例化;無(wú)變量衡招,只有靜態(tài)常量(static final)篱昔,因?yàn)橐凰械膶?shí)現(xiàn)類共享;類的繼承只能單繼承,但是接口可以一次實(shí)現(xiàn)多個(gè)州刽,用“,”隔開(kāi)空执。
5. super和 this對(duì)比
super:
super可以理解為是指向自己父類對(duì)象的一個(gè)指針,指的是離自己最近的一個(gè)父類穗椅。
用法:
super.成員名(變量名或者方法名):顯式調(diào)用父類的同名成員辨绊,當(dāng)然成員不能是private的(不允許子類訪問(wèn))。因?yàn)楫?dāng)子類和父類存在同名成員時(shí)匹表,因?yàn)樽宇惓蓡T優(yōu)先級(jí)更高门坷,此時(shí)會(huì)隱藏父類的相應(yīng)成員。
super(參數(shù)列表);:調(diào)用父類的構(gòu)造函數(shù)袍镀,注意super語(yǔ)句一定要放在函數(shù)體的第一條 :
this:
this可以理解為指向當(dāng)前對(duì)象自身的一個(gè)指針默蚌,即當(dāng)前正在執(zhí)行本方法的那個(gè)對(duì)象實(shí)例。位于函數(shù)體內(nèi)部苇羡。
用法:
this.成員名:引用成員變量绸吸。因?yàn)楹瘮?shù)參數(shù)或者函數(shù)中的局部變量和成員變量同名的話,成員變量被屏蔽设江,此時(shí)要訪問(wèn)成員變量則需要使用“this.成員變量”的方式引用惯裕。
this(參數(shù)列表);:調(diào)用本類中參數(shù)表一致的另一個(gè)構(gòu)造函數(shù),注意應(yīng)作為構(gòu)造函數(shù)中的第一條語(yǔ)句绣硝。
引用構(gòu)造函數(shù)時(shí):
super(參數(shù)):調(diào)用父類中的某一個(gè)構(gòu)造函數(shù)(應(yīng)該為構(gòu)造函數(shù)中的第一條語(yǔ)句)蜻势。this(參數(shù)):調(diào)用本類中另一種形式的構(gòu)造函數(shù)(應(yīng)該為構(gòu)造函數(shù)中的第一條語(yǔ)句)。
this和super都無(wú)需聲明鹉胖。
6. synchronize和 volatile對(duì)比
(1)作用范圍:volatile僅能使用在變量級(jí)別握玛;synchronized則可以使用在變量、方法甫菠、和類級(jí)別挠铲;
(2)volatile本質(zhì)是在告訴jvm當(dāng)前變量在寄存器(工作內(nèi)存)中的值是不確定的,需要從主存中讀燃庞铡拂苹;synchronized則是鎖定當(dāng)前變量,只有當(dāng)前線程可以訪問(wèn)該變量痰洒,其他線程被阻塞住瓢棒。
(3)volatile不會(huì)造成線程的阻塞;synchronized可能會(huì)造成線程的阻塞丘喻。
(4)volatile只能在線程內(nèi)存和主內(nèi)存之間同步一個(gè)變量的值脯宿,而synchronized則同步在線程內(nèi)存和主內(nèi)存之間的所有變量的值,通過(guò)鎖住和釋放監(jiān)聽(tīng)器來(lái)實(shí)現(xiàn)泉粉。
(5)volatile標(biāo)記的變量不會(huì)被編譯器優(yōu)化连霉;synchronized標(biāo)記的變量可以被編譯器優(yōu)化
(6)顯然榴芳,synchronized在性能上將比volatile更加有所消耗
(7)volatile僅能實(shí)現(xiàn)變量的修改可見(jiàn)性,不能保證原子性跺撼;而synchronized則可以保證變量的修改可見(jiàn)性和原子性
學(xué)習(xí)Java的同學(xué)注意了?吒小!歉井!
學(xué)習(xí)過(guò)程中遇到什么問(wèn)題或者想獲取學(xué)習(xí)資源的話肌括,歡迎加入Java學(xué)習(xí)交流群346942462,我們一起學(xué)Java酣难!