1. 程式人生 > >為什麼區域性變數需要顯式設定初始化值

為什麼區域性變數需要顯式設定初始化值

我們在程式設計中,無時無刻地都在於方法打交道,而在方法中,我們很難不使用區域性變數,比如我們有下面的這樣一段很簡單的程式碼

640?wx_fmt=png

隨著我們敲打出上面的程式碼,IDE也會同時拋給我們一個錯誤,就是 Variable 'localName' might not have been initialized

這是什麼錯誤,localName沒有初始化?為什麼成員變數是可以的的,不信你看

640?wx_fmt=png

是的,上面的成員變數是沒有問題,也沒有警告的。

這就奇怪了,這是為什麼呢,javac怎麼這麼蠢呢?

答案是否定的。javac足夠有能力推斷出區域性變數並初始化預設值。然而它並沒有這樣做。

想要弄清楚為什麼這樣做就,就需要搞清楚區域性變數和成員變數的關於賦值和取值的順序的差異。

對於成員變數而言,其賦值和取值訪問的先後順序具有不確定性。還是以這段程式碼為例。

640?wx_fmt=png

name的賦值可以發生在dumpField之前,也可以發生在dumpField之後。這是在執行時發生的,在編譯器來看確定不了的。對於沒把握的事情,javac是不會去做的,這種事情交給執行時的JVM就可以了。

而對於成員變數而言,其賦值和取值訪問順序是確定的。比如這段程式碼

640?wx_fmt=png

因為localName的作用範圍只限定於dump方法中,必然的順序就是先賦值(宣告),再進行訪問。

說了半天還沒有說區域性變數為什麼顯式設定初始值呢?

其實之所以這樣做就是一種對程式設計師的約束限制。因為程式設計師(人)是(有些情況下)是靠不住的,假使區域性變數可以使用預設值,我們總會無意間忘記賦值,進而導致不可預期的情況出現。這

“之所以設計成這樣完全是一種策略決定,並非是我力不能及,年輕人,我只能幫你到這裡了。”,Javac如是說。

瞭解Java的一些技術細節還是很有用的,這裡在最後推薦一個極客時間的課程,深入拆解JVM虛擬機器,Oracle研究院帶你入門JVM。推薦給所有希望進階的Java和Android程式設計師,值得擁有。

640?wx_fmt=png

相關推薦

為什麼區域性變數需要設定初始

我們在程式設計中,無時無刻地都在於方法打交道,而在方法中,我們很難不使用區域性變數,比如我們有下

設定一個全域性變數解決套件的初始裡面變數沒辦法存下來的問題

測試套件目錄 執行結束後,要和執行前一致 測試套件檔案 執行結束後,要和執行前一致 測試套件用例 執行結束後,要和執行前一致 核心就是為了設定一個全域性變數,解決了棘手的問題:套件的初始化話,變數沒辦法存下來的問題 還有就是初始化裡面建立的資料要留給後面用,動態產生的東西,就這樣儲存下來給後

C++中函數模板,具體化,實例

程序 使用 集合 typename 內容 方法 區分 bsp 代碼 函數模板 形如: template<typename T> //沒有分號 void func(T &a,T &b); 稱為函數模板,其中,template和typename為關

npm 工具(用來安裝和管理nodejs包的一個工具。所有使用nodejs第三方庫的項目,都需要在項目初始的時候 使用 npm init 命令來初始項目)

des auth 暫時 cif 通過 作用 hello amp `` 新建項目 npm init```package.json ```{ "name": "webpackdemo1", 項目名稱,包名,不能是grunt或webpack "version": "1.

為什麼lambda中用到的區域性變數需要為final

  區域性變數 區域性變數是儲存在棧上的,而棧上的內容在當前執行緒執行完成之後就會被GC回收掉。   lambda表示式 lambda表示式最終被處理為一個額外的執行緒去執行。絕對不是上面提到的執行緒。如果上面的執行緒執行完了,而這個執行緒又使用到了上面提到的區域性變數會出現錯誤

[Xcode10 實際操作]三、檢視控制器-(8)在Storyboard中設定初始檢視控制器

本文將演示如何設定故事板的初始檢視控制器。 開啟自動生成的預設故事板【Main.storyboard】 在開啟的故事板中,系統已經生成了一個空白的檢視控制器。 控制器左側的右向箭頭【→】,表示當前的控制器,是故事板的初始控制器。 接著開啟檢查器面板。在故事板元素列表中,選擇當前檢視控制器的根檢視。

android 開發如果api >= 23 需要申請許可權

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 如果api >= 23 需要顯式申請許

Mac環境變數配置錯了以後初始的方法

轉自:https://blog.csdn.net/or_7r_ccl/article/details/50886223 配置過安卓開發環境,改過bash_profile這個檔案,最後不知怎麼的只有cd命令能執行,我猜測可能修改bash_profile檔案後沒有儲存 導致的 儲存命令是: source .bas

ZTree 設定初始時勾選某個節點

//ZTree初始化所執行的方法         /* 先在callback 方法中設定如下,初始化樹時執行onAsyncSuccess 方法          &nbs

機器學習——什麼時候需要的劃分出“驗證集”

       所謂的顯式的劃分出“驗證集”,其實就是顯式的將資料集劃分為“訓練集”、“驗證集”、“測試集”。但是假如要使用k折交叉驗證來為模型進行超引數調優而言,是不需要顯式的將資料集劃分出“驗證集”的。        當資料集的整體比較小時,常常需要使用k折交叉驗證才能更

為什麼內部類訪問區域性變數需要加final修飾?

先看一段程式碼: public void myRun(final String name){ new Runnable() { public vo

MariaDB設定初始密碼及修改密碼

方法1:   [[email protected] ~]# mysql   MariaDB[(none)]> UPDATE mysql.user SET password = PASSWORD(‘newpassword’) WHERE USER = ‘ro

【C】為什麼靜態變數會被初始化為0,而自動變數卻不會被初始

把自動變數初始化為0的代價,將會增加函式呼叫的代價。C語言非常注重執行速度。 然而,把全域性變數區初始化為0,僅僅在程式啟動時候產生成本。這也許是這個問題的主要原因。 更精確的說,C++並不把靜態變數初始化為0,他們有自己的預設值,對於原生型別(native types)來

含有string成員的結構體變數,為什麼不能初始

struct CatInfo { string Title; int TotalCnt;} Cats[2]={{"S01",10},{"S02",10}}; 錯誤: Compiling...Yml.cppc:/documents and settings/administra

很奇怪的bootclasspath引數 同文章裡說的一樣,也沒有搞清楚 為什麼需要地指定一下-bootclasspath

http://blog.csdn.net/smilingleo/article/details/5005538 嘗試下面程式碼: import sun.util.resources.LocaleData;   publicclass SunTest{    

C++類靜態成員變數和const常量的初始方法

C++類靜態成員變數和const常量在定義類的時候就必須初始化,否則都會編譯出錯。 而具初始化方法為: C++類靜態成員變數初始化方法 [cpp] view plain copy  print? #include <iostream> #

為什麼要將區域性變數的作用域最小

嗨,本篇文章來說說 Java 的一個小細節:為什麼要將區域性變數的作用域最小化? 明人不說暗話啊。這篇文章的靈感來源於《Effective Java》,這本書我買了有好長好長一段時間了,書頁都已經泛黃,烙下了時間的痕跡,但我仍然還沒有把這本書讀完。說來慚愧啊。 為什麼呢?總感覺這本書的中文翻譯有點拙劣,讀

阿里巴巴Java開發手冊建議建立HashMap時設定初始容量,但是多少合適呢?

集合是Java開發日常開發中經常會使用到的,而作為一種典型的K-V結構的資料結構,HashMap對於Java開發者一定不陌生。 關於HashMap,很多人都對他有一些基本的瞭解,比如他和hashtable之間的區別、他和concurrentHashMap之間的區別等。這些都是比較常見的,關於HashMap的一

陣列元素的預設初始

對於基本資料型別的變數建立的陣列:byte,short,int,long,float,double,char,boolean:1.對於byte,short,long,int而言:建立陣列以後預設值為0 package com; public class V { public static v

UIPickerView內容居中顯示,設定初始預設

系統預設的是內容居左顯示的,有時會覺得不太好看,可以實現代理方法。 - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingV