Java:为什么我需要初始化一个原始的局部变量?

use*_*572 26 java primitive

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

print语句导致以下编译时错误,

局部变量f可能尚未初始化

如果Java中的原语已经有一个默认值(float = 0.0f),为什么我需要定义一个?


编辑:

所以,这很有效

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

感谢大家!

Zak*_*ria 47

因为它是一个局部变量.这就是它没有分配给它的原因:

局部变量略有不同; 编译器永远不会为未初始化的局部变量分配默认值.如果无法初始化声明它的局部变量,请确保在尝试使用它之前为其赋值.访问未初始化的局部变量将导致编译时错误.

编辑:为什么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++;
        }
...
Run Code Online (Sandbox Code Playgroud)

如陈述(if (!vset.testVar(local.number)) {),JDK检查(with testVar)是否分配了变量(我们可以找到代码Vset的源testVar代码).如果没有,它会var.not.initialized属性文件中引发错误:

...
javac.err.var.not.initialized=\
    Variable {0} may not have been initialized.
...
Run Code Online (Sandbox Code Playgroud)

资源

  • 哦哇,今天完全学到了新东西!:d (5认同)
  • 这并没有真正*解释*“为什么”,是吗? (2认同)

sar*_*old 16

实际上,编译器没有为您分配默认值float f,因为在这种情况下它是一个局部变量 - 而不是一个字段:

局部变量略有不同; 编译器永远不会为未初始化的局部变量分配默认值.如果无法初始化声明它的局部变量,请确保在尝试使用它之前为其赋值.访问未初始化的局部变量将导致编译时错误.


Mik*_*uel 7

类字段(final无论如何)都被初始化为默认值.局部变量不是.

声明字段时并不总是需要分配值.声明但未初始化的字段将由编译器设置为合理的默认值.

因此,一个(非final等)领域f

class C {
  float f;
}
Run Code Online (Sandbox Code Playgroud)

将被初始化0f,但局部变量f

void myMethod() {
  float f;
}
Run Code Online (Sandbox Code Playgroud)

不会是.

本地变量的处理方式与语言不同.局部变量具有良好的生命周期,因此在初始化之前的任何使用都可能是错误.字段不是这样,默认初始化通常很方便.


小智 5

实际上局部变量存储在堆栈中。因此有可能为局部变量采用任何旧值。出于安全原因,这是一个很大的挑战..因此java说你必须在使用前初始化局部变量。