在 Java 中,类变量,实例变量可以不经过主动赋值就直接使用,而局部变量在不主动赋值的情况下,是无法使用的。在下面分析一下这个原因:
1. 类变量
类变量的赋值有两次,两次都在类加载的过程中,类加载可以简单的分为加载,连接,初始化,其中连接又分为验证,准备,解析。
第一次赋值在准备阶段:为类的静态变量分配内存,并将其初始化为默认值
第二次赋值在初始化阶段:也就是执行 clint,就是自己的静态变量赋值和静态初始化块
所以,即使没有为类变量赋值,也会在准备阶段赋默认值
2. 实例变量
在使用 new 创建实例的时候,在字节码的层次起码会有 new, invokespecial 这两条字节码语句,其中在 new 字节码执行的时候,会创建实例,并将其实例变量(包括本类及其全部父类所定义的每个实例变量)初始化为各自的默认值
接着在执行 invokespecial 时,会执行 lint,也就是其中一个构造方法
可见在实例变量的赋值过程中,也会有两次赋值,所以即使没有主动赋值,也已经有了默认值了
3. 局部变量
但是在局部变量中,局部变量是存储在局部变量表中的(引用和基本类型,引用所指向的对象还是在堆中的);而局部变量表是属于栈帧的一部分,虚拟机完全没有给这里赋初值,所以不赋初值是无法使用的
总结
通过上面的描述,可以知道,类变量和实例变更都存在一次自动的赋默认值的情况,所以类变量,实例变量可以不经过主动赋值就直接使用,而局部变量在不主动赋值的情况下,是无法使用的