麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 編程 > Java > 正文

Java中final關(guān)鍵字詳解

2020-03-22 20:26:50
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
談到final關(guān)鍵字,想必很多人都不陌生,在使用匿名內(nèi)部類(lèi)的時(shí)候可能會(huì)經(jīng)常用到final關(guān)鍵字。另外,Java中的String類(lèi)就是一個(gè)final類(lèi),那么今天我們就來(lái)了解final這個(gè)關(guān)鍵字的用法。
主要介紹:一.final關(guān)鍵字的基本用法。二.深入理解final關(guān)鍵字一.final關(guān)鍵字的基本用法 在Java中,final關(guān)鍵字可以用來(lái)修飾類(lèi)、方法和變量(包括成員變量和局部變量)。下面就從這三個(gè)方面來(lái)了解一下final關(guān)鍵字的基本用法。 1.修飾類(lèi) 當(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方法。 在使用final修飾類(lèi)的時(shí)候,要注意謹(jǐn)慎選擇,除非這個(gè)類(lèi)真的在以后不會(huì)用來(lái)繼承或者出于安全的考慮,盡量不要將類(lèi)設(shè)計(jì)為final類(lèi)。 2.修飾方法 下面這段話摘自《Java編程思想》第四版第143頁(yè): “使用final方法的原因有兩個(gè)。第一個(gè)原因是把方法鎖定,以防任何繼承類(lèi)修改它的含義;第二個(gè)原因是效率。在早期的Java實(shí)現(xiàn)版本中,會(huì)將final方法轉(zhuǎn)為內(nèi)嵌調(diào)用。但是如果方法過(guò)于龐大,可能看不到內(nèi)嵌調(diào)用帶來(lái)的任何性能提升。在最近的Java版本中,不需要使用final方法進(jìn)行這些優(yōu)化了。“ 因此,如果只有在想明確禁止 該方法在子類(lèi)中被覆蓋的情況下才將方法設(shè)置為final的。 注:類(lèi)的private方法會(huì)隱式地被指定為final方法。 3.修飾變量 修飾變量是final用得最多的地方,也是本文接下來(lái)要重點(diǎn)闡述的內(nèi)容。首先了解一下final變量的基本語(yǔ)法: 對(duì)于一個(gè)final變量,如果是基本數(shù)據(jù)類(lèi)型的變量,則其數(shù)值一旦在初始化之后便不能更改;如果是引用類(lèi)型的變量,則在對(duì)其初始化之后便不能再讓其指向另一個(gè)對(duì)象。 舉個(gè)例子: 上面的一段代碼中,對(duì)變量i和obj的重新賦值都報(bào)錯(cuò)了。二.深入理解final關(guān)鍵字 在了解了final關(guān)鍵字的基本用法之后,這一節(jié)我們來(lái)看一下final關(guān)鍵字容易混淆的地方。1.類(lèi)的final變量和普通變量有什么區(qū)別? 當(dāng)用final作用于類(lèi)的成員變量時(shí),成員變量(注意是類(lèi)的成員變量,局部變量只需要保證在使用之前被初始化賦值即可)必須在定義時(shí)或者構(gòu)造器中進(jìn)行初始化賦值,而且final變量一旦被初始化賦值之后,就不能再被賦值了。 那么final變量和普通變量到底有何區(qū)別呢?下面請(qǐng)看一個(gè)例子:html' target='_blank'>public class Test { public static void main(String[] args) { String a = "hello2"; final String b = "hello"; String d = "hello"; String c = b + 2; String e = d + 2; System.out.println((a == c)); System.out.println((a == e));} true
false 大家可以先想一下這道題的輸出結(jié)果。為什么第一個(gè)比較結(jié)果為true,而第二個(gè)比較結(jié)果為fasle。這里面就是final變量和普通變量的區(qū)別了,當(dāng)final變量是基本數(shù)據(jù)類(lèi)型以及String類(lèi)型時(shí),如果在編譯期間能知道它的確切值,則編譯器會(huì)把它當(dāng)做編譯期常量使用。也就是說(shuō)在用到該final變量的地方,相當(dāng)于直接訪問(wèn)的這個(gè)常量,不需要在運(yùn)行時(shí)確定。這種和C語(yǔ)言中的宏替換有點(diǎn)像。因此在上面的一段代碼中,由于變量b被final修飾,因此會(huì)被當(dāng)做編譯器常量,所以在使用到b的地方會(huì)直接將變量b 替換為它的 值。而對(duì)于變量d的訪問(wèn)卻需要在運(yùn)行時(shí)通過(guò)鏈接來(lái)進(jìn)行。想必其中的區(qū)別大家應(yīng)該明白了,不過(guò)要注意,只有在編譯期間能確切知道final變量值的情況下,編譯器才會(huì)進(jìn)行這樣的優(yōu)化,比如下面的這段代碼就不會(huì)進(jìn)行優(yōu)化:public class Test { public static void main(String[] args) { String a = "hello2"; final String b = getHello(); String c = b + 2; System.out.println((a == c)); public static String getHello() { return "hello";} 這段代碼的輸出結(jié)果為false。2.被final修飾的引用變量指向的對(duì)象內(nèi)容可變嗎? 在上面提到被final修飾的引用變量一旦初始化賦值之后就不能再指向其他的對(duì)象,那么該引用變量指向的對(duì)象的內(nèi)容可變嗎?看下面這個(gè)例子:public class Test { public static void main(String[] args) { final MyClass myClass = new MyClass(); System.out.println(++myClass.i);class MyClass { public int i = 0;} 這段代碼可以順利編譯通過(guò)并且有輸出結(jié)果,輸出結(jié)果為1。這說(shuō)明引用變量被final修飾之后,雖然不能再指向其他對(duì)象,但是它指向的對(duì)象的內(nèi)容是可變的。3.final和static 很多時(shí)候會(huì)容易把static和final關(guān)鍵字混淆,static作用于成員變量用來(lái)表示只保存一份副本,而final的作用是用來(lái)保證變量不可變。看下面這個(gè)例子:public class Test { public static void main(String[] args) { MyClass myClass1 = new MyClass(); MyClass myClass2 = new MyClass(); System.out.println(myClass1.i); System.out.println(myClass1.j); System.out.println(myClass2.i); System.out.println(myClass2.j);class MyClass { public final double i = Math.random(); public static double j = Math.random();} 運(yùn)行這段代碼就會(huì)發(fā)現(xiàn),每次打印的兩個(gè)j值都是一樣的,而i的值卻是不同的。從這里就可以知道final和static變量的區(qū)別了。4.匿名內(nèi)部類(lèi)中使用的外部局部變量為什么只能是final變量? 這個(gè)問(wèn)題請(qǐng)參見(jiàn)上一篇博文中《Java內(nèi)部類(lèi)詳解》中的解釋?zhuān)诖颂幉辉儋樖觥?.關(guān)于final參數(shù)的問(wèn)題 關(guān)于網(wǎng)上流傳的”當(dāng)你在方法中不需要改變作為參數(shù)的對(duì)象變量時(shí),明確使用final進(jìn)行聲明,會(huì)防止你無(wú)意的修改而影響到調(diào)用方法外的變量“這句話,我個(gè)人理解這樣說(shuō)是不恰當(dāng)?shù)摹?因?yàn)闊o(wú)論參數(shù)是基本數(shù)據(jù)類(lèi)型的變量還是引用類(lèi)型的變量,使用final聲明都不會(huì)達(dá)到上面所說(shuō)的效果。 看這個(gè)例子就清楚了: 上面這段代碼好像讓人覺(jué)得用final修飾之后,就不能在方法中更改變量i的值了。殊不知,方法changeValue和main方法中的變量i根本就不是一個(gè)變量,因?yàn)閖ava參數(shù)傳遞采用的是值傳遞,對(duì)于基本類(lèi)型的變量,相當(dāng)于直接將變量進(jìn)行了拷貝。所以即使沒(méi)有final修飾的情況下,在方法內(nèi)部改變了變量i的值也不會(huì)影響方法外的i。 再看下面這段代碼:public class Test { public static void main(String[] args) { MyClass myClass = new MyClass(); StringBuffer buffer = new StringBuffer("hello"); myClass.changeValue(buffer); System.out.println(buffer.toString());class MyClass { void changeValue(final StringBuffer buffer) { buffer.append("world");} 運(yùn)行這段代碼就會(huì)發(fā)現(xiàn)輸出結(jié)果為 helloworld。很顯然,用final進(jìn)行修飾并沒(méi)有阻止在changeValue中改變buffer指向的對(duì)象的內(nèi)容。有人說(shuō)假如把final去掉了,萬(wàn)一在changeValue中讓buffer指向了其他對(duì)象怎么辦。有這種想法的朋友可以自己動(dòng)手寫(xiě)代碼試一下這樣的結(jié)果是什么,如果把final去掉了,然后在changeValue中讓buffer指向了其他對(duì)象,也不會(huì)影響到main方法中的buffer,原因在于java采用的是值傳遞,對(duì)于引用變量,傳遞的是引用的值,也就是說(shuō)讓實(shí)參和形參同時(shí)指向了同一個(gè)對(duì)象,因此讓形參重新指向另一個(gè)對(duì)象對(duì)實(shí)參并沒(méi)有任何影響。以上內(nèi)容就是Java中final關(guān)鍵字詳解,希望對(duì)大家有所幫助。PHP教程

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 黄色成人小视频 | 成人在线精品视频 | 99国产精品自拍 | 国产午夜精品一区二区三区四区 | 欧美成在人线a免费 | 91精品动漫在线观看 | 日本在线视频一区二区三区 | 久久久久久久免费精品 | 久久久三级免费电影 | 久久久久中精品中文字幕19 | 国产精品久久久久久久久久iiiii | 日韩av成人| h色视频在线观看 | 国产精品视频免费网站 | 在线观看视频毛片 | 久久精品视频免费观看 | 国产精品wwww | 成人午夜一区 | 2019亚洲日韩新视频 | 欧美三级一级 | 玖玖精品视频在线 | 欧美日韩大片在线观看 | 香蕉久久久精品 | 欧美一级黄色免费看 | 香蕉黄色网 | 欧美精品一区二区三区在线 | 成人国产精品一区二区毛片在线 | 奶子吧naiziba.cc免费午夜片在线观看 | 欧美三级欧美成人高清www | 免费成人 | 免费放黄网站在线播放 | 久久久精品网 | 日日噜噜噜夜夜狠狠久久蜜桃 | 成人视屏在线观看 | 中文字幕在线永久 | 在线日韩亚洲 | av在线免费观看国产 | 亚洲人成中文字幕在线观看 | 欧美大胆xxxx肉体摄影 | 亚洲五码在线观看视频 | 看片一区 |