[英]Variable might not have been initialized error
當我嘗試編譯這個時:
public static Rand searchCount (int[] x)
{
int a ;
int b ;
...
for (int l= 0; l<x.length; l++)
{
if (x[l] == 0)
a++ ;
else if (x[l] == 1)
b++ ;
}
...
}
我收到這些錯誤:
Rand.java:72: variable a might not have been initialized
a++ ;
^
Rand.java:74: variable b might not have been initialized
b++ ;
^
2 errors
在我看來,我在方法的頂部初始化了它們。 怎么了?
你聲明了它們,但你沒有初始化它們。 初始化它們是將它們設置為等於一個值:
int a; // This is a declaration
a = 0; // This is an initialization
int b = 1; // This is a declaration and initialization
你得到錯誤是因為你沒有初始化變量,但是你在for
循環中增加了它們(例如, a++
)。
Java原語具有默認值,但正如一位用戶在下面評論的那樣
當聲明為類成員時,它們的默認值為零。 局部變量沒有默認值
局部變量沒有默認值。 它們的初始值是未定義的,沒有通過某種方式分配值。 在你可以使用局部變量之前,它們必須被初始化。
當您在類級別(作為成員,即作為字段)和方法級別聲明變量時,存在很大差異。
如果您在類級別聲明一個字段,它們會根據其類型獲得默認值。 如果您在方法級別或作為塊聲明變量(表示 {} 內的任何代碼),則不會獲得任何值並保持未定義,直到它們以某種方式獲得一些起始值,即分配給它們的一些值。
如果它們被聲明為類的字段,那么它們將真正被初始化為 0。
你有點困惑,因為如果你寫:
class Clazz {
int a;
int b;
Clazz () {
super ();
b = 0;
}
public void printA () {
sout (a + b);
}
public static void main (String[] args) {
new Clazz ().printA ();
}
}
然后此代碼將打印“0”。 這是因為在創建 Clazz 的新實例時會調用一個特殊的構造函數。 首先調用super ()
,然后隱式初始化字段a
,然后執行b = 0
行。
您聲明了它們,但未初始化。
int a; // declaration, unknown value
a = 0; // initialization
int a = 0; // declaration with initialization
您聲明了它們,但沒有用值初始化它們。添加如下內容:
int a = 0;
您聲明了它們,但沒有為它們提供初始值 - 因此,它們未初始化。 嘗試類似:
public static Rand searchCount (int[] x)
{
int a = 0 ;
int b = 0 ;
並且警告應該消失。
由於沒有其他答案引用了 Java 語言標准,我決定自己寫一個答案:
在 Java 中,默認情況下,局部變量不會使用某個值進行初始化(例如,與類的字段不同)。 從語言規范一( §4.12.5 )可以閱讀以下內容:
局部變量(第 14.4 節、第 14.14 節)必須在使用前通過初始化(第 14.4 節)或賦值(第 15.26 節)顯式賦予一個值,其方式可以使用明確賦值規則(第16(明確的任務))。
因此,由於變量a
和b
未初始化:
for (int l= 0; l<x.length; l++)
{
if (x[l] == 0)
a++ ;
else if (x[l] == 1)
b++ ;
}
操作a++;
和b++;
無論如何,無法產生任何有意義的結果。 所以編譯器通知你這是合乎邏輯的:
Rand.java:72: variable a might not have been initialized
a++ ;
^
Rand.java:74: variable b might not have been initialized
b++ ;
^
但是,需要了解一個事實,即a++;
和b++;
無法產生任何有意義的結果與編譯器顯示錯誤的原因無關。 而是因為它是在 Java 語言規范中明確設置的
局部變量(§14.4、§14.14)必須顯式地賦予一個值(...)
為了展示上述觀點,讓我們將您的代碼更改為:
public static Rand searchCount (int[] x)
{
if(x == null || x.length == 0)
return null;
int a ;
int b ;
...
for (int l= 0; l<x.length; l++)
{
if(l == 0)
a = l;
if(l == 1)
b = l;
}
...
}
因此,即使上面的代碼可以被正式證明是有效的(即,變量a
和b
將始終分別賦值為0
和1
),嘗試分析應用程序的邏輯不是編譯器的工作,也不是局部變量初始化的規則是否依賴於此。 編譯器檢查變量a
和b
是否根據局部變量初始化規則進行初始化,並做出相應的反應(例如,顯示編譯錯誤)。
您在方法開始時聲明了它們,但從未初始化它們。 初始化會將它們設置為等於一個值,例如:
int a = 0;
int b = 0;
想象一下如果 x[l] 在循環中既不是 0 也不是 1 會發生什么。 在這種情況下, a 和 b 將永遠不會被分配並具有未定義的值。 您必須使用某個值初始化它們,例如 0。
在使用方法塊之前初始化方法塊內的局部變量是一個很好的做法。 這是初學者可能犯的錯誤。
public static void main(String[] args){
int a;
int[] arr = {1,2,3,4,5};
for(int i=0; i<arr.length; i++){
a = arr[i];
}
System.out.println(a);
}
您可能期望控制台會顯示“5”,但編譯器會拋出“變量 a 可能未初始化”錯誤。 盡管有人可能認為變量 a 在 for 循環中已“初始化”,但編譯器並不這么認為。 如果arr.length
為 0 怎么辦? for 循環根本不會運行。 因此,編譯器會給出variable a might not have been initialized
來指出潛在的危險並要求你初始化變量。
為防止此類錯誤,只需在聲明變量時對其進行初始化即可。
int a = 0;
您還沒有初始化a
和b
,只是聲明了它們。 有細微的差別。
int a = 0;
int b = 0;
至少這是針對 C++ 的,我認為 Java 是相同的概念。
將變量“a”設置為這樣的某個值,
a=0;
聲明和初始化都是不同的。
祝你好運
當我嘗試編譯時:
public static Rand searchCount (int[] x)
{
int a ;
int b ;
...
for (int l= 0; l<x.length; l++)
{
if (x[l] == 0)
a++ ;
else if (x[l] == 1)
b++ ;
}
...
}
我得到這些錯誤:
Rand.java:72: variable a might not have been initialized
a++ ;
^
Rand.java:74: variable b might not have been initialized
b++ ;
^
2 errors
在我看來,我在方法的頂部對其進行了初始化。 怎么了
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.