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);
}
}
みんな、ありがとう!
それはローカル変数だからです。これが、何も割り当てられていない理由です:
ローカル変数はわずかに異なります。コンパイラは、初期化されていないローカル変数にデフォルト値を割り当てることはありません。宣言されている場所でローカル変数を初期化できない場合は、使用する前に必ず値を割り当ててください。初期化されていないローカル変数にアクセスすると、コンパイル時エラーが発生します。
編集:なぜ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.
...
_
実際、コンパイラはしませんデフォルト値をfloat f
に割り当てます。この場合、これはローカル変数であり、フィールドではないためです。
ローカル変数はわずかに異なります。コンパイラは、初期化されていないローカル変数にデフォルト値を割り当てることはありません。宣言されている場所でローカル変数を初期化できない場合は、使用する前に必ず値を割り当ててください。初期化されていないローカル変数にアクセスすると、コンパイル時エラーが発生します。
クラスフィールド(とにかく非final
フィールド)はデフォルト値に初期化されます。ローカル変数はそうではありません。
フィールドが宣言されるときに値を割り当てる必要は必ずしもありません。宣言されているが初期化されていないフィールドは、コンパイラによって適切なデフォルトに設定されます。
したがって、final
のような(非f
)フィールド
class C {
float f;
}
0f
に初期化されますが、ローカル変数f
void myMethod() {
float f;
}
ならないだろう。
ローカル変数は、言語によってフィールドとは異なる方法で処理されます。ローカル変数の有効期間は十分にスコープされているため、初期化前に使用するとエラーになる可能性があります。フィールドはそうではないので、デフォルトの初期化が便利なことがよくあります。
実際には、ローカル変数はスタックに格納されます。したがって、ローカル変数に存在する古い値を取得する可能性があります。セキュリティ上の理由から、これは大きな課題です。したがって、Javaは、初期化する必要があると言います。使用前のローカル変数。
こんにちはみんなの解決策は簡単です。ヒープメモリに格納される値はコンパイラベースのデータ型によって初期化されますが、ローカル変数はスタックメモリに格納されるため、明示的に初期化する必要があります。