Gou*_*rav 53 java variables primitive-types
为什么必须在Java中初始化局部变量(包括基元)?为什么在实例变量的情况下不相同?
Jon*_*eet 67
最近有一个关于C#的问题 ...... - 在那里阅读答案,因为它基本上是一回事.您可能还会发现Eric Lippert最近的博客文章很有趣; 它至少在同一区域附近,尽管它的推力有些不同.
基本上,要求在读取变量之前为变量赋值是一件好事.这意味着你不会意外地阅读你不想要的东西.是的,变量可能有默认值 - 但是如果它能够证明你正在尝试读取可能尚未分配的东西,那么编译器是否能够更好地捕获你的bug?如果要为局部变量提供默认值,则可以始终明确指定.
现在这对于局部变量很好 - 但是例如和静态变量,编译器无法知道调用方法的顺序.在"getter"之前是否会调用属性"setter"?它无法知道,所以它无法提醒你危险.这就是为什么默认值被用于实例/静态变量-至少,你会得到一个已知值(0,假,空等),而不是仅仅"不管发生什么事情是在内存中的时间." (它还消除了读取未明确擦除的敏感数据的潜在安全问题.)
好吧,在局部变量的情况下,很清楚"之前"是什么意思,因为声明(在方法中)和引用之间的程序流是顺序的.如果在方法之外声明的字段,编译器永远不知道将要使用哪个代码,因此它不能生成错误,因为可能某些其他方法在使用之前初始化该字段.
在Java中,如果未手动初始化类和实例变量,则它们将采用默认值(null,0,false).但是,局部变量没有默认值.除非为局部变量赋值,否则编译器将拒绝编译读取它的代码.恕我直言,这导致了这样的结论:在声明它时,初始化一个带有一些默认值的局部变量(如null,后面可能会导致NullPointerException)实际上是一件坏事.请考虑以下示例:
Object o;
if (<some boolean condition>)
o = <some value>;
else
o = <some other value>;
System.out.println(o);
Run Code Online (Sandbox Code Playgroud)
o使用null 的初始化是完全没有必要的,因为Java编译器在编译时检查任何代码路径o在读取变量之前初始化(使用null或某些非null值).这意味着,System.out.println(o);如果您要o在上面的代码片段中注释掉变量的两个初始化中的任何一个,编译器将拒绝编译该行.
这适用于Java,也许仅适用于Java.我不知道像C#这样的语言.但是,在旧的C(也许是C++)中,仍然建议在声明变量AFAIK时始终初始化变量.这种"老派"编程语言可能是这样的原因,即总是初始化变量的建议出现在书籍和有关现代语言(如Java)的讨论中,其中编译会跟踪变量是否已初始化.
不完全正确.只有在引用时才需要初始化局部变量.如果从未引用,则局部变量可以保持未初始化.例如:
int x; // Valid
int y;
println("y=" + y); // Not valid since y's value has never been assigned
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32173 次 |
| 最近记录: |