三门峡 网站开发,网络架构需求,用asp做网站有哪控件,网站的竞争对手之前一直认为static块是在class load的时候执行#xff0c;今天在验证Spring初始化Context loader的时候#xff0c;发现bean的static块并没有执行。Class A{static{System.out.println(static block invoked!)}}那么static块到底在什么时候运行的呢#xff1f;…之前一直认为static块是在class load的时候执行今天在验证Spring初始化Context loader的时候发现bean的static块并没有执行。Class A{static{System.out.println(static block invoked!)}}那么static块到底在什么时候运行的呢如果了解JVM原理我们知道一个类的运行分为以下步骤装载连接初始化其中装载阶段又三个基本动作组成通过类型的完全限定名产生一个代表该类型的二进制数据流解析这个二进制数据流为方法区内的内部数据结构创建一个表示该类型的java.lang.Class类的实例另外如果一个类装载器在预先装载的时遇到缺失或错误的class文件它需要等到程序首次主动使用该类时才报告错误。连接阶段又分为三部分验证确认类型符合Java语言的语义检查各个类之间的二进制兼容性(比如final的类不用拥有子类等)另外还需要进行符号引用的验证。准备Java虚拟机为类变量分配内存设置默认初始值。解析(可选的) 在类型的常量池中寻找类接口字段和方法的符号引用把这些符号引用替换成直接引用的过程。当一个类被主动使用时Java虚拟就会对其初始化如下六种情况为主动使用当创建某个类的新实例时(如通过new或者反射克隆反序列化等)当调用某个类的静态方法时当使用某个类或接口的静态字段时当调用Java API中的某些反射方法时比如类Class中的方法或者java.lang.reflect中的类的方法时当初始化某个子类时当虚拟机启动某个被标明为启动类的类(即包含main方法的那个类)Java编译器会收集所有的类变量初始化语句和类型的静态初始化器将这些放到一个特殊的方法中clinit。实际上static块的执行发生在“初始化”的阶段。初始化阶段jvm主要完成对静态变量的初始化静态块执行等工作。下面我们看看执行static块的几种情况1、第一次new A()的过程会打印因为这个过程包括了初始化2、第一次Class.forName(A)的过程会打印因为这个过程相当于Class.forName(A,true,this.getClass().getClassLoader());3、第一次Class.forName(A,false,this.getClass().getClassLoader())的过程则不会打印。因为false指明了装载类的过程中不进行初始化。不初始化则不会执行static块。参考资料深入Java虚拟机