注意:我很清楚初始化它可以解决问题;我只是假设编译器会遵循执行路径,并且看到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;
没有编译问题,但为什么我需要这样做?
答案 0 :(得分:5)
如果要输入块,编译器无法确定您是第一个。如果没有,则foo
将保持未初始化状态。您无法在未初始化的变量上调用add
。您可以通过length
最终来帮助编译器。然后,编译器将知道将执行第一个if
块。
final int length = 5;
答案 1 :(得分:5)
本地变量需要在其他地方使用之前进行初始化,因为默认情况下不会对其进行初始化。如果if()
不是true
,该怎么办?
if (length > 3)
{
foo = new ArrayList<String>();
}
编译器无法判断条件是否为真。
局部变量(§14.4,§14.13)必须在使用之前通过初始化(§14.4)或赋值(§15.26),以一种可以由编译器使用明确赋值的规则
正如@jlordo所指出的,将length
作为final
将解决编译错误,因为在编译时本身编译器知道length
的值始终为{{ 1}}因此条件5
总是length>3
所以局部变量将被初始化。
答案 2 :(得分:2)
因为默认情况下未初始化本地实例,与类或对象实例不同。
来自Java Language Specification:
本地变量(第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.
答案 3 :(得分:1)
这是因为foo在分支中初始化。所以编译器不确定foo是否会被初始化。
答案 4 :(得分:1)
实例和类变量初始化为null或0值。但局部变量不是。因此,您必须在使用之前初始化局部变量。