5

注意:我很清楚初始化它可以解决问题;我只是假设编译器会遵循执行路径,并看到 foo 实际上会在它暗示它“可能”不是的点被初始化。

我最初的假设是,如果长度从不超过 3,我将永远不需要分配内存来使用它。

这永远不会在生产中使用,我只是好奇

请参阅以下示例: -

List<String> foo;

int length = 5;

if (length > 3)
{
    foo = new ArrayList<String>();
}

if (length > 4)
{
    foo.add("bar");
}

为什么这会导致显示以下内容?

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

当然,在分支之后,永远不会出现 foo 未初始化的情况。我知道如果我要这样做:-

List<String> foo = null;

不会有编译问题,但为什么我需要这样做?

4

5 回答 5

5

如果将输入块,编译器无法确定您是第一个。如果没有,那么foo将保持未初始化状态。您不能调用add未初始化的变量。length您可以通过制作final来帮助编译器。然后编译器将知道第一个if块将被执行。

final int length = 5;
于 2013-06-15T17:16:26.040 回答
5

局部变量需要在在其他任何地方使用之前进行初始化,因为默认情况下它不会被初始化。如果if()不是true怎么办?

if (length > 3)
{
    foo = new ArrayList<String>();
}

编译器无法判断条件是否为真。

局部变量(第 14.4 节、第 14.13 节)必须在使用之前通过初始化(第 14.4 节)或赋值(第 15.26 节)显式地赋予一个值,编译器可以使用明确的规则来验证任务

正如@jlordo 指出的那样,制作lengthasfinal将解决编译错误,因为在编译时编译器本身知道 的值length将始终为5,因此条件length>3始终true如此,因此将初始化局部变量。

于 2013-06-15T17:16:33.520 回答
2

因为与类或对象实例不同,默认情况下不初始化本地实例。

来自Java 语言规范

局部变量(第 14.4 节、第 14.14 节)必须在使用前通过初始化(第 14.4 节)或赋值(第 15.26 节)显式地赋予一个值,编译器可以使用明确的规则来验证分配(§16)。

默认值:

For type byte, the default value is zero, that is, the value of (byte)0.
For type short, the default value is zero, that is, the value of (short)0.
For type int, the default value is zero, that is, 0.
For type long, the default value is zero, that is, 0L.
For type float, the default value is positive zero, that is, 0.0f.
For type double, the default value is positive zero, that is, 0.0d.
For type char, the default value is the null character, that is, '\u0000'.
For type boolean, the default value is false.
For all reference types (§4.3), the default value is null. 
于 2013-06-15T17:17:29.120 回答
1

发生这种情况是因为 foo 在分支中被初始化。所以编译器不确定 foo 是否会被初始化。

于 2013-06-15T17:16:31.827 回答
1

实例和类变量被初始化为 null 或 0 值。但局部变量不是。所以你必须在使用它之前初始化局部变量。

于 2013-06-15T17:18:20.687 回答