众所周知,在Java中,需要在使用之前初始化局部变量(参见JLS)
在使用本地变量(第14.4节,第14.14节)之前,必须明确给出一个值 初始化(§14.4)或赋值(§15.26),以可验证的方式 使用明确赋值的规则(§16)。
否则会出现编译错误:
The local variable result may not have been initialized.
这个设计决定的理由是什么?为什么编译器不会自动将声明(例如int x
,double y
,String foo
等)转换为使用某个默认值(0,0.0,null)初始化的定义?这样做有什么缺点吗?
答案 0 :(得分:6)
缺点是默认值可能不是您想要的 - 您可能只是忘记初始化本地变量,然后使用默认值可能会导致异常(或者更糟糕的是,只是运行创建一些难以跟踪的下来。)
在这种情况下强制编译错误可确保您更正问题并明确将其分配给您想要的任何内容。
相同的参数可以应用于字段,但是在读取该值之前检查它们是否已分配值更难(并且在技术上不可能),因为它们可能是从任何地方访问或写入。因此,在这种情况下使用默认值而不是强制执行此规则是唯一合理的方法。
答案 1 :(得分:0)
只是为了说明浆果词。
int x;
float y;
y = 42/x;
String name;
print("Hello " + name);
很遗憾,但这些是不执行该政策的语言中最常见的错误。 请记住,每个变量的默认值都可能不同,这就是开发人员设置它们的原因。
答案 2 :(得分:0)
添加@ berry120答案 - 关于字段和变量之间的区别。
未针对变量进行初始化
“未初始化”状态的行为与final
字段或变量的行为几乎相同,只是可以重新分配值(我将其称为“最终行为”)。所以它让你不要忘记在这样的分支中初始化它:
int x;
if(condition1){
x = 10;
} else
if(condition2){
if( condition3 ){
x = 20;
} // else branch is missing here
} else {
x = 40;
}
所以编译器会在这里提示我一个初始化错误。为什么不将final
用于相同的目的并且具有var的默认值?更多打字&冗长+我可能想重新分配给这个变种。
字段的默认值
我认为具有默认值是实例变量的首选,因为使用“最终行为”初始化变量对于具有许多构造函数的类来说可能是一个真正的痛苦。当你对这个类进行子类化和/或使用循环引用时,它可能会变成一个真正的痛苦......或者一个难题:How to initialize a circular dependency (final fields referencing each other)?。
因此,对于实例字段,“结果可能尚未初始化”似乎不切实际。