簡體   English   中英

變量可能未初始化錯誤

[英]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(明確的任務))。

因此,由於變量ab未初始化:

 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;
    }

    ...   
}

因此,即使上面的代碼可以被正式證明是有效的(即,變量ab將始終分別賦值為01 ),嘗試分析應用程序的邏輯不是編譯器的工作,也不是局部變量初始化的規則是否依賴於此。 編譯器檢查變量ab是否根據局部變量初始化規則進行初始化,並做出相應的反應例如,顯示編譯錯誤)。

您在方法開始時聲明了它們,但從未初始化它們。 初始化會將它們設置為等於一個值,例如:

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;

您還沒有初始化ab ,只是聲明了它們。 有細微的差別。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM