2011-11-29 415 views
2

我知道局部變量是分配在堆棧上的,因爲成員變量或實例變量分配在堆上。但是我很好奇,爲什麼JVM不能爲堆棧上的局部變量分配一個默認值(如果它沒有賦值)(調用該方法時)?這與編譯器/ JVM /處理器的工作方式有關嗎?局部變量在使用前必須被初始化,例如變量,沒有這樣的限制,爲什麼?

+1

[未初始化變量和Java成員](http:// stackoverflow。com/questions/268814 /未初始化變量和成員在Java) – dogbane

回答

6

它可以。但是,最常見的錯誤之一是無意中未初始化的局部變量。根據定義制定非法的這些錯誤可以通過靜態分析來捕獲這些錯誤。

JLS 3, in section "4.12.5 Initial Values of Variables"

局部變量(§14.4,§14.14)必須被明確地給出的值 在使用之前,通過任一初始化(§14.4)或分配 (§15.26),可以通過編譯器使用 規則進行明確分配(§16)來驗證。

0

你爲什麼要這樣的行爲?如果你聲明一個變量用於本地使用,你是不是想盡快將它初始化爲它所需的初始值?實例變量初始化爲實例初始化時的默認值,因爲它們的生命週期大於聲明和初始化的範圍。

+0

我的問題是從其他角度。在C中,聲明的變量總是有一些默認值。那麼爲什麼在java中不一樣呢?當然,必須有理由。這就是我的問題所在。 – Santosh

0

這不是堆棧/堆問題。 Java的設計有幾個很好的簡單編程風格的項目。 你想要一個對象被毫無疑問地初始化。對於局部變量,編譯器在初始化之前可能會很容易地發出警告。此外,樣式聲明+初始化是期望的:

int n = takeN(); 

初始化將需要歸零堆棧幀,這是不必要的開銷。

1

局部變量存儲在堆棧中,並且在初始化之前不會實際創建。如果不使用局部變量,則不會進入堆棧。所以如果你想使用任何本地變量,你應該初始化它。

但是,實例變量分配在堆中,因此具有默認的佔位符。

如果沒有手動初始化,所有實例變量都有一些默認值。

+0

_So如果你想使用任何本地變量,你應該定義它。定義或初始化? – Santosh

+0

好吧,通過定義(**不聲明)我的意思是初始化。因爲那是你的變量實際上會被創建的時候。順便更新了我的答案。 – gprathour

0

這可能有幾個原因。一對夫婦:

首先,如前所述,未初始化的變量是錯誤的主要來源,雖然檢查未初始化的實例變量是不切實際的,但編譯器很容易檢查並「診斷」未初始化的局部變量 - 它實際上是在數據流分析的額外努力下付諸東流。

其次,初始化局部變量需要時間。實例變量可以通過簡單地將實例歸零來「初始化」,並且它只需要爲每個實例發生一次(並且需要爲「安全」和GC目的完成),但局部變量在這裏和那裏被分配 - 一些在堆棧中,一些在寄存器中,並且清除它們每次調用方法都需要實際的週期。

相關問題