我们在编程中, 无时无刻地都在于方法打交道, 而在方法中, 我们很难不使用局部变量, 比如我们有下面的这样一段很简单的代码
- public void dump() {
- String localName;
- System.out.println("dump localName=" + localName);
- }
随着我们敲打出上面的代码, IDE 也会同时抛给我们一个错误, 就是
Variable 'localName' might not have been initialized
这是什么错误, localName 没有初始化? 为什么成员变量是可以的的, 不信你看
- public class Test {
- public String name;
- public void dumpField() {
- System.out.println("dumpField name=" + name);
- }
- }
是的, 上面的成员变量是没有问题, 也没有警告的.
这就奇怪了, 这是为什么呢, javac 怎么这么蠢呢?
答案是否定的. javac 足够有能力推断出局部变量并初始化默认值. 然而它并没有这样做.
想要弄清楚为什么这样做就, 就需要搞清楚局部变量和成员变量的关于赋值和取值的顺序的差异.
对于成员变量而言, 其赋值和取值访问的先后顺序具有不确定性. 还是以这段代码为例.
- public class Test {
- public String name;
- public void dumpField() {
- System.out.println("dumpField name=" + name);
- }
- }
name 的赋值可以发生在 dumpField 之前, 也可以发生在 dumpField 之后. 这是在运行时发生的, 在编译器来看确定不了的. 对于没把握的事情, javac 是不会去做的, 这种事情交给运行时的 JVM 就可以了.
而对于成员变量而言, 其赋值和取值访问顺序是确定的. 比如这段代码
- public void dump() {
- String localName;
- System.out.println("dump localName=" + localName);
- }
因为 localName 的作用范围只限定于 dump 方法中, 必然的顺序就是先赋值(声明), 再进行访问.
说了半天还没有说局部变量为什么显式设置初始值呢?
其实之所以这样做就是一种对程序员的约束限制. 因为程序员 (人) 是(有些情况下)是靠不住的, 假使局部变量可以使用默认值, 我们总会无意间忘记赋值, 进而导致不可预期的情况出现. 这
"之所以设计成这样完全是一种策略决定, 并非是我力不能及, 年轻人, 我只能帮你到这里了.",Javac 如是说.
来源: https://juejin.im/entry/5b4bec3be51d451907695783