Java變量和對(duì)象的作用域
大多數(shù)程序設(shè)計(jì)語(yǔ)言都提供了“作用域”(Scope)的概念。
對(duì)于在作用域里定義的名字,作用域同時(shí)決定了它的“可見(jiàn)性”以及“存在時(shí)間”。在C,C++和Java里,作用域是由花括號(hào)的位置決定的。
變量的作用域
例子:
{
int x = 12;
/* only x available */
{
int q = 96;
/* both x & q available */
}
/* only x available */
/* q “out of scope” */
}
Java用一對(duì)大括號(hào)作為語(yǔ)句塊的范圍,稱為作用域,作為在作用域里定義的一個(gè)變量,它只有在哪個(gè)作用域結(jié)束之前才可使用。
在Java中不能像下面這樣書寫代碼:
{
int x = 12;
{
int x = 96; /* illegal */
}
}
Java編譯器會(huì)認(rèn)為變量已被定義,所以作用域中的變量不能重復(fù)定義,但是在C和C++中能將一個(gè)變量“隱藏”在一個(gè)更大的作用域里,在C和C++中被允許,在Java中是不允許的,因?yàn)镴ava的設(shè)計(jì)者認(rèn)為這樣做使程序產(chǎn)生了混淆。
再來(lái)看兩個(gè)例子,為了讓大家看到效果這里使用截圖的方式:
①

②

我們?cè)賮?lái)看這段代碼,大家思考一個(gè)問(wèn)題,第11行和第12行為什么沒(méi)有語(yǔ)法錯(cuò)誤?代碼如下:


如果我們交換一下位置呢,代碼如下:

離開(kāi)作用域,變量所分配的內(nèi)存空間將被JVM回收,所以語(yǔ)法不會(huì)有錯(cuò)誤,而第二種寫法name并沒(méi)有離開(kāi){}作用域,所以會(huì)語(yǔ)法錯(cuò)誤。
上述的變量都是局部變量,那么如果是在有全局變量的情況下又是怎樣一種結(jié)果呢?我們來(lái)用代碼說(shuō)話,代碼如下:

大家仔細(xì)的觀察并結(jié)合代碼思考,可以得出變量的作用域結(jié)論如下:
在同一作用域范圍的包裹下全局變量名和局部變量名是可以變量名相同的,在同一個(gè)作用域范圍的包裹下局部變量和局部變量不可以變量名相同(作用域內(nèi)不能重復(fù)命名),使用變量的時(shí)候如果不指明使用全局變量還是局部變量,那么默認(rèn)的就是使用局部的那個(gè)變量,但是如果局部變量超出了它本身的作用域范圍則會(huì)失效,被JVM垃圾回收,那么則可以重復(fù)命名此變量,并使用最新定義的這個(gè)局部變量。
對(duì)象的作用域
Java對(duì)象不具備與朱類型一樣的存在時(shí)間。用new關(guān)鍵字創(chuàng)建一個(gè)Java對(duì)象的時(shí)候,它會(huì)超出作用域的范圍之外。所以假若使用下面這段代碼:
{
String s = new String("a string");
} /* 作用域的終點(diǎn) */
那么句柄s,也就是引用會(huì)在作用域的終點(diǎn)處消失。然而,s指向的String對(duì)象依然占據(jù)著內(nèi)存空間。在上面這段代碼里,我們沒(méi)有辦法繼續(xù)使用這個(gè)對(duì)象,因?yàn)橹赶蛩奈ㄒ灰粋€(gè)句柄已經(jīng)超出了作用域的邊界。
這樣造成的結(jié)果是:對(duì)于用new創(chuàng)建的對(duì)象,只要我們?cè)敢?,它們就?huì)一直保留下去。這個(gè)編程問(wèn)題在C和C++里特別突出。在C++里遇到的麻煩最大:由于不能從語(yǔ)言獲得任何幫助,所以在需要對(duì)象的時(shí)候,根本無(wú)法確定它們是否可用。而且最麻煩的是,在C++里,一旦完成工作,必須保證將對(duì)象手動(dòng)清除。
這樣便帶來(lái)了一個(gè)有趣的問(wèn)題。假如 Java 讓對(duì)象依然故我,怎樣才能防止它們大量充斥內(nèi)存,并最終造成程序的“凝固”呢。在 C++里,這個(gè)問(wèn)題最令程序員頭痛。但 Java 以后,情況卻發(fā)生了改觀。 Java 有一個(gè)特別的“垃圾收集器”,它會(huì)查找用 new 創(chuàng)建的所有對(duì)象,并辨別其中哪些不再被引用。隨后,它會(huì)自動(dòng)釋放由那些閑置對(duì)象占據(jù)的內(nèi)存,以便能由新對(duì)象使用。這意味著我們根本不必操心內(nèi)存的回收問(wèn)題。只需簡(jiǎn)單地創(chuàng)建對(duì)象,一旦不再需要它們,它們就會(huì)自動(dòng)離去。這樣做可防止在 C++里很常見(jiàn)的一個(gè)編程問(wèn)題:由于程序員忘記釋放內(nèi)存造成的“內(nèi)存溢出”。
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
SpringBoot+JWT實(shí)現(xiàn)單點(diǎn)登錄完美解決方案
單點(diǎn)登錄是一種統(tǒng)一認(rèn)證和授權(quán)機(jī)制,指在多個(gè)應(yīng)用系統(tǒng)中,用戶只需要登錄一次就可以訪問(wèn)所有相互信任的系統(tǒng),不需要重新登錄驗(yàn)證,這篇文章主要介紹了SpringBoot+JWT實(shí)現(xiàn)單點(diǎn)登錄解決方案,需要的朋友可以參考下2023-07-07
spring-boot報(bào)錯(cuò)java: 程序包javax.servlet.http不存在
當(dāng)springboot項(xiàng)目從2.7.x的升級(jí)到3.0.x的時(shí)候,會(huì)遇到一個(gè)問(wèn)題java: 程序包javax.servlet.http不存在,下面就來(lái)具體介紹一下,感興趣的可以了解一下2024-08-08
第三方包jintellitype實(shí)現(xiàn)Java設(shè)置全局熱鍵
本文主要介紹了,在java中使用第三方插件包jintellitype來(lái)實(shí)現(xiàn)全局熱鍵,非常的簡(jiǎn)單,但是很實(shí)用,有需要的朋友可以參考下,歡迎一起來(lái)參與改進(jìn)此項(xiàng)目2014-09-09
Springboot hibernate envers使用過(guò)程詳解
這篇文章主要介紹了Springboot hibernate envers使用過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
springboot項(xiàng)目啟動(dòng)的時(shí)候,運(yùn)行main方法報(bào)錯(cuò)NoClassDefFoundError問(wèn)題
這篇文章主要介紹了springboot項(xiàng)目啟動(dòng)的時(shí)候,運(yùn)行main方法報(bào)錯(cuò)NoClassDefFoundError問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
Java 定時(shí)器的多種實(shí)現(xiàn)方式
本文介紹了Java中定時(shí)器的多種實(shí)現(xiàn)方式,有此需求的朋友可以根據(jù)實(shí)際選擇適合自己的方式2021-06-06
Spring?Cloud?Gateway遠(yuǎn)程命令執(zhí)行漏洞分析(CVE-2022-22947)
使用Spring Cloud Gateway的應(yīng)用程序在Actuator端點(diǎn)啟用、公開(kāi)和不安全的情況下容易受到代碼注入的攻擊,攻擊者可以惡意創(chuàng)建允許在遠(yuǎn)程主機(jī)上執(zhí)行任意遠(yuǎn)程執(zhí)行的請(qǐng)求,這篇文章主要介紹了Spring?Cloud?Gateway遠(yuǎn)程命令執(zhí)行漏洞(CVE-2022-22947),需要的朋友可以參考下2023-03-03
反射機(jī)制:getDeclaredField和getField的區(qū)別說(shuō)明
這篇文章主要介紹了反射機(jī)制:getDeclaredField和getField的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06

