日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

java final keyword

發(fā)布時(shí)間:2025/3/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java final keyword 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?? 依據(jù)上下文環(huán)境,java的keywordfinal也存在著細(xì)微的差別,但通常指的是“這是無法改變的。”不想改變的理由由兩種:一種是效率,還有一種是設(shè)計(jì)。因?yàn)閮蓚€(gè)原因相差非常遠(yuǎn),所以關(guān)鍵子final可能被吳用。

?? 接下來介紹一下使用到fianl的三中情況:數(shù)據(jù),方法,類。

??

?? final數(shù)據(jù)

???很多編程語(yǔ)言都有某種方法,來向編譯器告知一塊數(shù)據(jù)是恒定不變的。有時(shí)數(shù)據(jù)的恒定不變是非常實(shí)用的,比如:

1,一個(gè)編譯時(shí)恒定不變的常量

2,一個(gè)在執(zhí)行時(shí)初始化,而你不希望它被改變。

?? 對(duì)于編譯期常量的這樣的情況,編譯器能夠?qū)⒃摮A恐荡氩徽撌裁纯赡苡玫剿挠?jì)算式中,也就是說,能夠在編譯期就執(zhí)行計(jì)算式,這減輕了一些執(zhí)行時(shí)的負(fù)擔(dān)。在java中,這類常量必須是基本類型,而且以final表示。在對(duì)這個(gè)常量定義時(shí),必須進(jìn)行賦值。

?? 一個(gè)即是static又是fianl的域僅僅占一段不能改變的存儲(chǔ)空間。

?? 當(dāng)final應(yīng)用于對(duì)象引用時(shí),而不是基本類型時(shí),其含義有些讓人疑惑。對(duì)基本類型使用fianl不能改變的是他的數(shù)值。而對(duì)于對(duì)象引用,不能改變的是他的引用,而對(duì)象本身是能夠改動(dòng)的。一旦一個(gè)final引用被初始化指向一個(gè)對(duì)象,這個(gè)引用將不能在指向其它對(duì)象。java并未提供對(duì)不論什么對(duì)象恒定不變的支持。這一限制也通用適用于數(shù)組,它也是對(duì)象。

?? 以下的事例示范fianl域的情況。注意,依據(jù)慣例,即是static又是fianl的域(即編譯器常量)將用大寫表示,并用下劃切割個(gè)單詞:

package reusing; //: reusing/FinalData.java // The effect of final on fields. import java.util.*; import static net.mindview.util.Print.*; class Value { int i; // Package access public Value(int i) { this.i = i; } } public class FinalData { private static Random rand = new Random(47); private String id; public FinalData(String id) { this.id = id; } // Can be compile-time constants: private final int valueOne = 9; private static final int VALUE_TWO = 99; // Typical public constant: public static final int VALUE_THREE = 39; // Cannot be compile-time constants: private final int i4 = rand.nextInt(20); static final int INT_5 = rand.nextInt(20); private Value v1 = new Value(11); private final Value v2 = new Value(22); private static final Value VAL_3 = new Value(33); // Arrays: private final int[] a = { 1, 2, 3, 4, 5, 6 }; public String toString() { return id + ": " + "i4 = " + i4 + ", INT_5 = " + INT_5; } public static void main(String[] args) { FinalData fd1 = new FinalData("fd1"); //! fd1.valueOne++; // Error: can't change value fd1.v2.i++; // Object isn't constant! fd1.v1 = new Value(9); // OK -- not final for(int i = 0; i < fd1.a.length; i++) fd1.a[i]++; // Object isn't constant! //! fd1.v2 = new Value(0); // Error: Can't //! fd1.VAL_3 = new Value(1); // change reference //! fd1.a = new int[3]; print(fd1); print("Creating new FinalData"); FinalData fd2 = new FinalData("fd2"); print(fd1); print(fd2); } } /* Output: fd1: i4 = 15, INT_5 = 18 Creating new FinalData fd1: i4 = 15, INT_5 = 18 fd2: i4 = 13, INT_5 = 18 */

???? 因?yàn)関alueOne和VALUE_TWO都是帶有編譯時(shí)數(shù)值的fianl基本類型,所以它們二者均能夠用作編譯期常量,而且沒有重大差別。VALUE_THREE是一種更加典型的對(duì)常量進(jìn)行定義的方式:定義為public,能夠被不論什么人訪問;定義為static,則強(qiáng)調(diào)僅僅有一份;定義為fianl,這說明它是個(gè)常量。請(qǐng)注意帶有恒定初始值(即,編譯期常量)的final static基本類型全用大寫字母命名,而且字母與字母之間用下劃線隔開。

?? 我們不能由于某些數(shù)據(jù)是fianl的就覺得在編譯時(shí)能夠知道它的值。在執(zhí)行時(shí)使用隨機(jī)數(shù)來初始化i4和INT_5的值叫說明了這一點(diǎn)。事例部分也展示了將fianl數(shù)據(jù)定義為static和非static的差別。此差別僅僅有當(dāng)數(shù)值在執(zhí)行時(shí)內(nèi)被初始化時(shí)才會(huì)顯現(xiàn),這是由于在編譯器對(duì)編譯時(shí)的數(shù)值一視同仁(而且他們可能由于優(yōu)化而消失)。當(dāng)執(zhí)行時(shí)會(huì)看見這個(gè)差別。請(qǐng)注意,在此fd1和fd2中i4的值是唯一的,每次都會(huì)被初始化為15,13。INT_5的值是不能夠通過創(chuàng)建第二個(gè)FinalData對(duì)象加以改變的。這是由于他是static的,在裝載類時(shí)(也就是第一次創(chuàng)建這個(gè)類對(duì)象時(shí))已經(jīng)被初始化,而不是每次創(chuàng)建都初始化。

???


假設(shè)看上面的事例來理解我標(biāo)記顏色的的部分有點(diǎn)困難的話,請(qǐng)看以下的事例:

???

?public class B3 { static Random r =new Random(12); final int int1= r.nextInt(100);//產(chǎn)生0-99的隨機(jī)數(shù) static final int INT_2= r.nextInt(100); public static void main(String[] args) { B3 b1=new B3(); System.out.println("int1:"+b1.int1+" INT_2:"+b1.INT_2); B3 b2=new B3(); //b2.INT_2=100;//錯(cuò)誤的賦值 System.out.println("int1:"+b2.int1+" INT_2:"+b2.INT_2); } }

啟動(dòng)main()先運(yùn)行的是B3 b1=new B3();,創(chuàng)建B3的第一個(gè)對(duì)象,這將會(huì)先初始化static final int INT_2= r.nextInt(100);,然后是初始化final int int1= r.nextInt(100);,所以第一條輸出語(yǔ)句的結(jié)果是int1:12??? INT_2:66。接下來創(chuàng)建B3的第二個(gè)對(duì)象,這也會(huì)導(dǎo)致B3類中成員的初始化,但static final int INT_2= r.nextInt(100);不會(huì)在被初始化,為什么前面已經(jīng)提過。輸出的結(jié)果是int1:56??? INT_2:66。兩次的輸出INT_2的值都是一樣的。

?? 在說回我們的第一個(gè)事例,V1到VAL_3說明final引用的意義。正如在main()方法中看見的,能夠改變對(duì)象數(shù)組a的值,但不能將a的引用指向還有一個(gè)對(duì)象。看起來使基本類型成為fianl比引用類型成為final的用處大。

??? java或許生成"空白final",所謂空白final是指被聲明為final但又未給初值的域。不管什么情況下編譯器都會(huì)保證final域在使用前初始化。但空白final在fianl的使用上提供了非常大的靈活性,為此,一個(gè)fianl域能夠依據(jù)某些對(duì)象有所不同,卻又保持恒定不變的特性。以下的事例說明了一點(diǎn)。

?class Poppet { private int i; Poppet(int ii) { i = ii; } } public class BlankFinal { private final int i = 0; // Initialized final private final int j; // Blank final private final Poppet p; // Blank final reference // Blank finals MUST be initialized in the constructor: public BlankFinal() { j = 1; // Initialize blank final p = new Poppet(1); // Initialize blank final reference } public BlankFinal(int x) { j = x; // Initialize blank final p = new Poppet(x); // Initialize blank final reference } public static void main(String[] args) { new BlankFinal(); new BlankFinal(47); } } //

?

final 參數(shù)

????? java中或許將參數(shù)列表中的參數(shù)以聲明的方式聲指明為final。這意味著你無發(fā)改變參數(shù)所指向的對(duì)象。

class Gizmo { public void spin() {} } public class FinalArguments { void with(final Gizmo g) { //! g = new Gizmo(); // Illegal -- g is final } void without(Gizmo g) { g = new Gizmo(); // OK -- g not final g.spin(); } // void f(final int i) { i++; } // Can't change // You can only read from a final primitive: int g(final int i) { return i + 1; } public static void main(String[] args) { FinalArguments bf = new FinalArguments(); bf.without(null); bf.with(null); } } //

方法f()g()展示了基本類型的參數(shù)被指定為final是所出現(xiàn)的結(jié)果:你能夠讀參數(shù),但不能改動(dòng)參數(shù)。這一特性僅僅要用來向匿名內(nèi)部類傳遞數(shù)據(jù)。

final 方法

?? 使用final方法有兩個(gè)原因。第一個(gè)原因是把方法鎖定,以防止不論什么繼承它的類改動(dòng)它的含義。這是出于設(shè)計(jì)的考慮:想要確保在繼承中使用的方法保持不變,而且不會(huì)被覆蓋。

?? 過去建議使用final方法的第二個(gè)原因是效率。在java的早期實(shí)現(xiàn)中,假設(shè)將一個(gè)方法指明為fianl,就是允許編譯器將針對(duì)該方法的全部調(diào)用都轉(zhuǎn)為內(nèi)嵌調(diào)用。當(dāng)編譯器發(fā)現(xiàn)一個(gè)final方法調(diào)用命令時(shí),它會(huì)依據(jù)自己的慎重推斷,跳過插入程序代碼這樣的正常的調(diào)用方式而運(yùn)行方法調(diào)用機(jī)制(將參數(shù)壓入棧,跳至方法代碼處運(yùn)行,然后跳回并清理?xiàng)V械膮?shù),處理返回值),而且以方法體中的實(shí)際代碼的副本來取代方法調(diào)用。這將消除方法調(diào)用的開銷。當(dāng)然,假設(shè)一個(gè)方法非常大,你的程序代碼會(huì)膨脹,因而可能看不到內(nèi)嵌所帶來的性能上的提高,由于所帶來的性能會(huì)花費(fèi)于方法內(nèi)的時(shí)間量而被縮減。

??? 上面標(biāo)顏色的地方不太懂。不知道那位看過Java編程思想和知道的高人給解釋解釋。

??? 在最進(jìn)的java版本號(hào)中,虛擬機(jī)(特別是hotspot技術(shù))能夠探測(cè)到這些情況,并優(yōu)化去掉這些效率反而減少的額外的內(nèi)嵌調(diào)用,因此不再須要使用final方法來進(jìn)行優(yōu)化了。其實(shí),這樣的做法正逐漸受到勸阻。在使用java se5/6時(shí),應(yīng)該讓編譯器和JVM去處理效率問題,僅僅有在想明白禁止覆蓋式,才將方法設(shè)置為fianl的。

??? final和privatekeyword

???類中的全部private方法都是隱式的制定為final的。因?yàn)槟銦o法訪問private方法你也就無法覆蓋它。能夠?qū)rivate方法加入final修飾詞,但這毫無意義。

class WithFinals { // Identical to "private" alone: private final void f() { print("WithFinals.f()"); } // Also automatically "final": private void g() { print("WithFinals.g()"); } } class OverridingPrivate extends WithFinals { private final void f() { print("OverridingPrivate.f()"); } private void g() { print("OverridingPrivate.g()"); } } class OverridingPrivate2 extends OverridingPrivate { public final void f() { print("OverridingPrivate2.f()"); } public void g() { print("OverridingPrivate2.g()"); } }

???? "覆蓋"僅僅有在某方法是基類接口的一部分時(shí)才會(huì)發(fā)生。即,必須將一個(gè)對(duì)象向上轉(zhuǎn)型為它的基類并條用同樣的方法。假設(shè)某方法是private的,它就不是基類接口的一部分。它僅是一些隱藏于類中的程序代碼,假設(shè)一個(gè)基類中存在某個(gè)private方法,在派生類中以同樣的名稱創(chuàng)建一個(gè)public,protected或包訪問權(quán)限方法的話,該方法僅僅只是是與基類中的方法有同樣的名稱而已,并沒有覆蓋基類方法。由于private方法無法觸及且有非常好的隱藏性,所以把它看成是由于他所屬類的組織結(jié)的原因而存在外,其它不論什么事物都不用考慮。

??? final 類

??? 當(dāng)將類定義為final時(shí),就表明了你不打算繼承該類,并且也不或許別人這樣做。換句話說,出于某種考慮,你對(duì)該類的設(shè)計(jì)永不須要做不論什么變動(dòng),或者出于安全的考慮,你不希望他有子類。

class SmallBrain {} final class Dinosaur { int i = 7; int j = 1; SmallBrain x = new SmallBrain(); void f() {} } //! class Further extends Dinosaur {} // error: Cannot extend final class 'Dinosaur' public class Jurassic { public static void main(String[] args) { Dinosaur n = new Dinosaur(); n.f(); n.i = 40; n.j++; } }

??? 請(qǐng)注意,final類的域能夠依據(jù)個(gè)人的意愿選擇是或不是final。不論類是否被定義為final,相同的規(guī)則相同適用于定義為final的域。然而,由于final是無法繼承的,所以被final修飾的類中的方法都隱式的制定為fianl,由于你無法覆蓋他們。在fianl類中能夠給方法加入final,但這不會(huì)產(chǎn)生不論什么意義。

轉(zhuǎn)載于:https://www.cnblogs.com/mengfanrong/p/4297540.html

總結(jié)

以上是生活随笔為你收集整理的java final keyword的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: a在线观看免费 | 懂色av懂色av粉嫩av分享吧 | 亚洲午夜在线视频 | 羞辱狗奴的句子有哪些 | 水牛影视av一区二区免费 | 99精品久久久久久中文字幕 | 97久久精品视频 | 国产做爰xxxⅹ高潮视频12p | 日本久久综合网 | 亚洲欧美一二三区 | 亚洲一区二区三区av无码 | 欧美色图另类 | 欧美黄网站在线观看 | 成人精品在线看 | 久久91亚洲人成电影网站 | 日韩不卡高清 | 99ri精品| 苍井空亚洲精品aa片在线播放 | 日本一区二区三区免费看 | 国产精品999. | av色综合 | 国产精品国产成人国产三级 | 日韩和的一区二区 | melody在线高清免费观看 | 日韩v欧美 | 日韩a在线播放 | 成年人黄色片网站 | 亚洲偷自| 99热99在线 | 永久免费未网 | 久久久久成人精品免费播放动漫 | 蜜桃在线一区二区 | www色| 国产懂色av | 日韩精品福利视频 | 屁屁影院国产第一页 | 黄色国产在线播放 | 天天草夜夜操 | 亚洲h| 国产视频123区 | 野花视频在线免费观看 | 一本色道久久综合亚洲精品酒店 | 久久亚洲影视 | 日本高清不卡视频 | 91麻豆精品国产午夜天堂 | 强伦人妻一区二区三区视频18 | 欧美激情一区二区三区在线 | 国产精品亚洲а∨天堂免在线 | 亚洲第一综合网站 | 日韩精品午夜 | 麻豆视频在线免费看 | 99久久香蕉 | 久久久性色精品国产免费观看 | 国产精品一区二区性色av | 91天天综合 | 精品人妻一区二区三区蜜桃 | 亚洲激情婷婷 | 午夜亚洲天堂 | 国产精品久久久久久久久久久久久久久久久 | 学生调教贱奴丨vk | 五月天黄色网址 | 我不卡一区二区 | 五十路毛片| 色噜噜狠狠一区二区三区牛牛影视 | 97se在线视频| 欧美成人二区 | 国产成人超碰人人澡人人澡 | 人妻 校园 激情 另类 | 樱花av在线| 欧美一二在线 | 国产精品欧美一区二区三区 | 日本丰满熟妇videossex一 | 51国产偷自视频区视频 | 欧美日韩不卡视频 | 四虎网站在线播放 | 久久er99热精品一区二区介绍 | 亚洲福利精品视频 | 欧美日韩激情网 | 亚洲一区无 | 丝袜美女啪啪 | 久久午夜视频 | 亚洲乱码日产精品bd在线观看 | 手机看片99| 一区二区在线免费 | 探花国产精品一区二区 | 国产精品手机视频 | 国产精品情侣 | 国产精品精品久久久久久 | 久久精品视频2 | 精品国产一级 | 香蕉视频在线播放 | 天天干干干干干 | 国产福利av| 伊人222成人综合网 亚洲日本中文 | 亚洲激情社区 | 欧美日韩三级在线 | aa视频在线观看 | 中文字幕女同女同女同 | 禁断介护av |