关于类加载的时候,static代码块中可以赋值但不能引用的问题


关于类加载的时候,static代码块中可以赋值但不能引用的问题

类加载过程

image-20200925104632965

先看代码:

class StaticTest{
    static {
        a=10;
        System.out.println(a);//报错:Illegal forward reference
    }
    static int a=1;

    public static void main(String[] args) {
        StaticTest staticTest = new StaticTest();
    }
}

编译不通过,报错信息说非法的前向引用,因为对于a的声明在下面的静态变量中,属于语法错误,jvm编译不通过。

如果去掉输出这句,变成下面的代码:

class StaticTest{
    static {
        a=10;
    }
    static int a=1;

    public static void main(String[] args) {
        StaticTest staticTest = new StaticTest();
        System.out.println(a);
    }
}

输出结果为:1

问题:为什么a还没有被声明就可以被赋值,为什么不报错?

答:

1.类加载的时候在连接阶段的准备中,做了下面的事情:

为类的静态变量分配内存并设置默认初始值,这些变量所使用的内存都将在方法区中进行分配。

注意:

这时候进行内存分配的仅包括类变量(static),而不包括实例变量,实例变量会在对象实例化的时候随对象一起分配到堆中。
这些内存都将在方法区中分配
非常量(final)的静态数据类型被默认赋对应类型的零值(如0、0L、null、false等),而不是程序中显示的赋值。

准备阶段检测到了aint,分配内存并为a赋初值0

2.然后进入初始化阶段之后,对静态代码块执行初始化,静态变量显示初始化。

初始化的顺序为代码排列顺序。如静态代码块在静态变量声明前,静态变量a在静态代码块和静态变量中分别做了赋值,则a先被静态代码块赋值,后被静态变量赋值语句赋值。并且静态语句块只能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块可以赋值,但是不能访问

所以说初始化之前a=0,先执行static代码块,a=10;然后执行静态变量,a=1;


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM