web-dev-qa-db-ja.com

Java:プリミティブローカル変数を初期化する必要があるのはなぜですか?

public class Foo {
    public static void main(String[] args) {
        float f;
        System.out.println(f);
    }
}

Printステートメントにより、次のコンパイル時エラーが発生します。

ローカル変数fが初期化されていない可能性があります

Javaのプリミティブにすでに デフォルト値(float = 0.0f) がある場合、なぜそれを定義する必要があるのですか?


編集:

だから、これはうまくいく

public class Foo {
    float f;
    public static void main(String[] args) {
        System.out.println(new Foo().f);
    }
}

みんな、ありがとう!

26
user1329572

それはローカル変数だからです。これが、何も割り当てられていない理由です:

ローカル変数はわずかに異なります。コンパイラは、初期化されていないローカル変数にデフォルト値を割り当てることはありません。宣言されている場所でローカル変数を初期化できない場合は、使用する前に必ず値を割り当ててください。初期化されていないローカル変数にアクセスすると、コンパイル時エラーが発生します。

編集:なぜJavaこのコンパイルエラーが発生するのですか?_IdentifierExpression.Java_ クラスファイル、このブロックが見つかります:

_...
if (field.isLocal()) {
            LocalMember local = (LocalMember)field;
            if (local.scopeNumber < ctx.frameNumber && !local.isFinal()) {
                env.error(where, "invalid.uplevel", id);
            }
            if (!vset.testVar(local.number)) {
                env.error(where, "var.not.initialized", id);
                vset.addVar(local.number);
            }
            local.readcount++;
        }
...
_

述べたように(if (!vset.testVar(local.number)) {)、JDKは変数が割り当てられているかどうかを(testVarで)チェックします( Vsetのソースコード ここでtestVarコードを見つけることができます)。そうでない場合は、 プロパティファイル からエラー_var.not.initialized_が発生します:

_...
javac.err.var.not.initialized=\
    Variable {0} may not have been initialized.
...
_

ソース

46
Zakaria

実際、コンパイラはしませんデフォルト値をfloat fに割り当てます。この場合、これはローカル変数であり、フィールドではないためです。

ローカル変数はわずかに異なります。コンパイラは、初期化されていないローカル変数にデフォルト値を割り当てることはありません。宣言されている場所でローカル変数を初期化できない場合は、使用する前に必ず値を割り当ててください。初期化されていないローカル変数にアクセスすると、コンパイル時エラーが発生します。

16
sarnold

クラスフィールド(とにかく非finalフィールド)はデフォルト値に初期化されます。ローカル変数はそうではありません。

フィールドが宣言されるときに値を割り当てる必要は必ずしもありません。宣言されているが初期化されていないフィールドは、コンパイラによって適切なデフォルトに設定されます。

したがって、finalのような(非f)フィールド

class C {
  float f;
}

0fに初期化されますが、ローカル変数f

void myMethod() {
  float f;
}

ならないだろう。

ローカル変数は、言語によってフィールドとは異なる方法で処理されます。ローカル変数の有効期間は十分にスコープされているため、初期化前に使用するとエラーになる可能性があります。フィールドはそうではないので、デフォルトの初期化が便利なことがよくあります。

6
Mike Samuel

実際には、ローカル変数はスタックに格納されます。したがって、ローカル変数に存在する古い値を取得する可能性があります。セキュリティ上の理由から、これは大きな課題です。したがって、Javaは、初期化する必要があると言います。使用前のローカル変数。

2
ram

こんにちはみんなの解決策は簡単です。ヒープメモリに格納される値はコンパイラベースのデータ型によって初期化されますが、ローカル変数はスタックメモリに格納されるため、明示的に初期化する必要があります。

1
user3728743