大多數程序設計語言都提供了「做用域」(Scope)的概念。程序員
對於在做用域裏定義的名字,做用域同時決定了它的「可見性」以及「存在時間」。在C,C++和Java裏,做用域是由花括號的位置決定的。編程
變量的做用域spa
例子:設計
1 { 2 int x = 12; 3 /* only x available */ 4 { 5 int q = 96; 6 /* both x & q available */ 7 } 8 /* only x available */ 9 /* q 「out of scope」 */ 10 }
Java用一對大括號做爲語句塊的範圍,稱爲做用域,做爲在做用域裏定義的一個變量,它只有在哪一個做用域結束以前纔可以使用。code
在Java中不能像下面這樣書寫代碼:對象
1 { 2 int x = 12; 3 { 4 int x = 96; /* illegal */ 5 } 6 }
Java編譯器會認爲變量已被定義,因此做用域中的變量不能重複定義,可是在C和C++中能將一個變量「隱藏」在一個更大的做用域裏,在C和C++中被容許,在Java中是不容許的,由於Java的設計者認爲這樣作使程序產生了混淆。blog
再來看兩個例子,爲了讓你們看到效果這裏使用截圖的方式:內存
①作用域
②get
咱們再來看這段代碼,你們思考一個問題,第11行和第12行爲何沒有語法錯誤?代碼以下:
若是咱們交換一下位置呢,代碼以下:
離開做用域,變量所分配的內存空間將被JVM回收,因此語法不會有錯誤,而第二種寫法name並無離開{}做用域,因此會語法錯誤。
上述的變量都是局部變量,那麼若是是在有成員變量的狀況下又是怎樣一種結果呢?咱們來用代碼說話,代碼以下:
你們仔細的觀察並結合代碼思考,能夠得出變量的做用域結論以下:
在同一做用域範圍的包裹下成員變量名和局部變量名是能夠變量名相同的,在同一個做用域範圍的包裹下局部變量和局部變量不能夠變量名相同(做用域內不能重複命名),在方法中使用變量的時候若是不指明使用成員變量仍是局部變量,那麼默認的就是使用局部的那個變量,可是若是局部變量超出了它自己的做用域範圍則會失效,被JVM垃圾回收,那麼則能夠重複命名此變量,並使用最新定義的這個局部變量。
對象的做用域
Java對象不具有與主類型同樣的存在時間。用new關鍵字建立一個Java對象的時候,它會超出做用域的範圍以外。因此倘若使用下面這段代碼:
1 { 2 String s = new String("a string"); 3 } /* 做用域的終點 */
那麼句柄s,也就是引用會在做用域的終點處消失。然而,s指向的String對象依然佔據着內存空間。在上面這段代碼裏,咱們沒有辦法繼續使用這個對象,由於指向它的惟一一個句柄已經超出了做用域的邊界。
這樣形成的結果是:對於用new建立的對象,只要咱們願意,它們就會一直保留下去。這個編程問題在C和C++裏特別突出。在C++裏遇到的麻煩最大:因爲不能從語言得到任何幫助,因此在須要對象的時候,根本沒法肯定它們是否可用。並且最麻煩的是,在C++裏,一旦完成工做,必須保證將對象手動清除。
這樣便帶來了一個有趣的問題。假如 Java 讓對象依然故我,怎樣才能防止它們大量充斥內存,並最終形成程序的「凝固」呢。在 C++裏,這個問題最令程序員頭痛。但 Java 之後,狀況卻發生了改觀。 Java 有一個特別的「垃圾收集器」,它會查找用 new 建立的全部對象,並辨別其中哪些再也不被引用。隨後,它會自動釋放由那些閒置對象佔據的內存,以便能由新對象使用。這意味着咱們根本沒必要操心內存的回收問題。只需簡單地建立對象,一旦再也不須要它們,它們就會自動離去。這樣作可防止在 C++裏很常見的一個編程問題:因爲程序員忘記釋放內存形成的「內存溢出」。
結束語:萬丈高樓平地起、冰凍三尺非一日之寒,作任何事情很難一蹴而就,大部分事情都應該善始善終。
可愛博主:AlanLee
博客地址:http://www.cnblogs.com/AlanLee
本文出自博客園,歡迎你們加入博客園。