我刚刚发现Java以不同的方式处理变量初始化。
情况1:
class A {
boolean x;
public static void main(String[] args) {
A a = new A();
System.out.println(a.x);
}
}
当我在程序上方运行时,输出显示为“ false”。但是现在我要发布其他代码:
情况2:
class A {
public static void main(String[] args) {
boolean x;
System.out.println(x);
}
}
现在,上面的代码表明
java.lang.Error: Unresolved compilation problem:
The local variable x may not have been initialized
为什么同一件事以不同的方式处理? 预先感谢!
答案 0 :(得分:4)
摘自Java Primitive Data Types上的Oracle文档:
局部变量略有不同;编译器从不分配 默认值为未初始化的局部变量。如果你不能 在声明它的地方初始化本地变量,确保 在尝试使用它之前给它分配一个值。正在访问 未初始化的局部变量将导致编译时错误。
所以这是一个有趣的细微差别。如果在本地声明了原始类型变量,则必须为其指定一个值。
答案 1 :(得分:2)
有三种不同类型的变量:
假设变量不是最终变量。 前两个默认为0或false(当var是基元时)或 进行读取访问时为null(当var是一个对象时)。在读取之前,必须将最后一个值设置为一个值,否则代码将无法编译。
如果将所有变量类型(本地,成员,静态)定义为final,则必须为其分配特定值。静态最终变量的此类初始化可以是对值的内联分配,也可以在静态初始化块中完成。最终成员变量的初始化可以在Initialization块中或在对象的构造函数中内联完成(最常见-最佳实践)。 最终的局部变量将内联初始化。当编译器发现该变量不会更改时,还会推断出一个“有效最终变量”。最终变量允许编译器处理和优化数据处理。
那只是开始的几个基本项目。希望对您有所帮助。
干杯。
答案 2 :(得分:0)
如果这个问题是关于为什么将局部变量与非最终成员变量区别对待的:在上面的示例中,我看不到有任何用处,请声明boolean x;
而不是boolean x = false;
,而是最后一个使程序员的意图明确。另外,如果以后初始化boolean x;
,则可以声明x
。在这里,您遇到的编译器错误会有所帮助,因此不要忘记在极少数情况下将其初始化。编译器无法检查是否默认将其初始化。
像这样的代码也很常见
int i;
if (a > b)
i = 8; // loong code
else
i = 42; // loong code
在这里初始化i
是没有用的。
静态成员和非静态成员(非最终成员)有所不同,因为在运行初始化程序和构造函数之前,编译器始终使所有字段为空。不手动将它们初始化为0会稍微改善性能。
答案 3 :(得分:0)
您的两个示例使用不同种类的变量:
仅当变量具有值/引用实例时,才能使用该变量。对于字段,如果您未明确分配值,则将默认值。对于 local 变量,不是情况并非如此,因此是错误。
对象的默认值为1, 1, $400, $900 --the $400 is £100+$300, the $900 is $400+$500
,图元的特殊值为默认值,例如null
,0
,0.0
等。
JLS明确定义了这种行为并解释了它的工作方式。看一下4.12.5 Initial Values of Variables章中的说明(相关摘录):
程序中的每个变量都必须具有一个值,然后才能使用它的值: