web-dev-qa-db-ja.com

変数が初期化されていない可能性があるエラー

これをコンパイルしようとすると:

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

私はメソッドの先頭でそれらを初期化したようです。どうしたの?

56
David

あなたは宣言済みそれらを初期化していません。それらを初期化すると、値に等しく設定されます。

int a;        // This is a declaration
a = 0;        // This is an initialization
int b = 1;    // This is a declaration and initialization

変数を初期化していないためエラーが発生しますが、forループで変数をインクリメントします(たとえば、a++)。

Javaプリミティブにはデフォルト値がありますが、1人のユーザーが以下にコメントしています

クラスメンバーとして宣言された場合、デフォルト値はゼロです。ローカル変数にはデフォルト値がありません

87
mipadi

ローカル変数はデフォルト値を取得しません。それらの初期値は、何らかの方法で値を割り当てることなく未定義です。ローカル変数を使用する前に、初期化する必要があります。

クラスレベル(メンバーとして、つまりフィールドとして)とメソッドレベルで変数を宣言する場合、大きな違いがあります。

クラスレベルでフィールドを宣言すると、タイプに応じてデフォルト値が取得されます。メソッドレベルまたはブロック({}内の任意のコードを意味する)で変数を宣言する場合、値を取得せず、何らかの方法で開始値、つまり割り当てられた値を取得するまで未定義のままにします。

74
reddy

それらがクラスのフィールドとして宣言された場合、実際には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行が実行されます。

6
Roman

それらを宣言しましたが、初期化されていません。

int a; // declaration, unknown value
a = 0; // initialization
int a = 0; // declaration with initialization
4
Konrad Garus

それらを宣言しましたが、値で初期化しませんでした。次のようなものを追加します。

int a = 0;
3
Jerome

メソッドの開始時に宣言しましたが、初期化することはありません。初期化すると、次のような値に等しく設定されます。

int a = 0;
int b = 0;
2
Thomas Owens

あなたはそれらを宣言しましたが、初期値を提供しませんでした-したがって、それらは初期化されていません。次のようなものを試してください:

public static Rand searchCount (int[] x)  
{ 
  int a = 0 ;  
  int b = 0 ; 

そして、警告は消えるはずです。

2
Bob Jarvis

ループ内でx [l]が0でも1でもない場合に何が起こるか想像してください。その場合、aとbは決して割り当てられず、未定義の値を持ちます。これらの両方を何らかの値、たとえば0で初期化する必要があります。

2
codymanix

メソッドブロックを使用する前に、メソッドブロック内のローカル変数を初期化することをお勧めします。ここに初心者が犯すかもしれない間違いがあります。

  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;
1
jackycflau

aおよびbを初期化しておらず、それらを宣言しただけです。微妙な違いがあります。

int a = 0;
int b = 0;

少なくともこれはC++の場合です。Javaも同じ概念であると思います。

1
Andy Shellam

変数「a」を次のような値に設定します。

a=0;

宣言と初期化は両方とも異なります。

幸運を

1
Rishabh Agarwal