之前一直认为static块是在class load的时候执行,今天在验证Spring初始化Context loader的时候,发现bean的static块并没有执行。

Java代码:

1 Class A{   
2 static{
3 System.out.println("static block invoked!")
4 }
5 }

那么static块到底在什么时候运行的呢?如果了解JVM原理,我们知道,一个类的运行分为以下步骤:

  1. 装载
  2. 连接
  3. 初始化

其中装载阶段又三个基本动作组成:

  1. 通过类型的完全限定名,产生一个代表该类型的二进制数据流
  2. 解析这个二进制数据流为方法区内的内部数据结
  3. 构创建一个表示该类型的java.lang.Class类的实例

另外如果一个类装载器在预先装载的时遇到缺失或错误的class文件,它需要等到程序首次主动使用该类时才报告错误。

连接阶段又分为三部分:

  1. 验证,确认类型符合Java语言的语义,检查各个类之间的二进制兼容性(比如final的类不用拥有子类等),另外还需要进行符号引用的验证。
  2. 准备,Java虚拟机为类变量分配内存,设置默认初始值。
  3. 解析(可选的) ,在类型的常量池中寻找类,接口,字段和方法的符号引用,把这些符号引用替换成直接引用的过程。

  当一个类被主动使用时,Java虚拟就会对其初始化,如下六种情况为主动使用:

  1. 当创建某个类的新实例时(如通过new或者反射,克隆,反序列化等)
  2. 当调用某个类的静态方法时
  3. 当使用某个类或接口的静态字段时
  4. 当调用Java API中的某些反射方法时,比如类Class中的方法,或者java.lang.reflect中的类的方法时
  5. 当初始化某个子类时
  6. 当虚拟机启动某个被标明为启动类的类(即包含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 static代码块执行时机的更多相关文章

  1. java的static块执行时机

    一.误区:简单认为JAVA静态代码块在类被加载时就会自动执行.证错如下: class MyClass1 { static {//静态块 System.out.println("static  ...

  2. Java中static块执行时机

    Java中static块执行时机 演示例子 在使用static进行初始化的操作,怎么也执行不了!代码如下: public class StaticDemo { public static final ...

  3. java的static块执行时机<转>

    一.误区:简单认为JAVA静态代码块在类被加载时就会自动执行.证错如下: class MyClass1 { static {//静态块 System.out.println("static  ...

  4. Java中static代码块,{}大括号代码块,构造方法代码块执行顺序!

    注:下列代码中的注释都是JUnit4单元测试运行结果. 首先,没有父类的(父类是Object)的类A package Static.of; public class A { { System.out. ...

  5. java静态代码块、初始化块和构造方法的执行顺序

    分析:当执行new Child()时,它首先去看父类里面有没有静态代码块,如果有,它先去执行父类里面静态代码块里面的内容,当父类的静态代码块里面的内容执行完毕之后,接着去执行子类(自己这个类)里面的静 ...

  6. java代码块执行顺序

    父类 public class Father { public Father() { System.out.println("父类构造PUBLIC father"); } stat ...

  7. 零零碎碎的java知识:static属性、普通属性、static代码块、普通代码块、构造函数

    本文中结论仅经本机测试,不保证在别的环境下成立.如果有什么不成立的地方务必告诉我_(:_」∠)_ java的内存是动态分配的,其机制和c/c++相当不一样……emmm在此不表. static: ·st ...

  8. 牛客网Java刷题知识点之关键字static、static成员变量、static成员方法、static代码块和static内部类

    不多说,直接上干货! 牛客网Java刷题知识点之关键字static static代表着什么 在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中st ...

  9. java静态代码块/静态属性、构造块、构造方法执行、main方法、普通代码块的顺序

    java静态代码块/静态属性.构造块.构造方法执行.main方法.普通代码块的顺序 这也是在笔试中的一个重要的考点,就有一个输出语句让你写出输出的结果. 理论知识: 静态代码块是:属于类的,在类加载时 ...

随机推荐

  1. 沉淀,再出发——在Hadoop集群之上安装hbase

    在Hadoop集群之上安装hbase 一.安装准备 首先我们确保在ubuntu16.04上安装了以下的产品,java1.8及其以上,ssh,hadoop集群,其次,我们需要从hbase的官网上下载并安 ...

  2. 32位 64位 获得进程peb的方法

    基于上一篇文章,大概了解了peb的获取方法,但是那个方法只能获得当前进程的PEB,不能获得其他的进程的PEB.根据那个思想,获得其他进程PEB则需要注入,得到进程信息,然后进程间通信,将信息返回来,经 ...

  3. 关于PHP上传文件失败但是找不到原因的问题?

    确定上传文件的前后台代码都准确无误后,可以考虑是不是PHP配置文件中限制了上传文件的大小 1.找到根目录中的PHP文件夹 2.点击当前正在使用的的PHP版本 3.搜索php.ini 4.打开 phpF ...

  4. WCF 双向通讯实例-简易的聊天程序

    源码下载 程序分四个部分: 1.原理 使用WCF的nettcp绑定.nettcp绑定类似原来的RPC,即.net remoting,只是在WCF提供统一协定,同一服务可以拥有多种客户端. 2.代码展示 ...

  5. android中OpenMax的实现【2】AwesomePlayer中openmax的入口

    AwesomePlayer 中有个变量 OMXClient mClient; 让我们看看   OMXClient class OMXClient { public: OMXClient(); stat ...

  6. 打印iframe某区域

    <a href="#" onClick="parent.iframe名字.focus();window.print();">打印</a>

  7. 如果有人问你CAP理论是什么,就把这篇文章发给他。

    绝对和你在网上看到的CAP定理介绍不一样. CAP 定理(CAP theorem)又被称作布鲁尔定理(Brewer's theorem),是加州大学伯克利分校的计算机科学家埃里克·布鲁尔(Eric B ...

  8. 集合异常之Set接口

    Set接口,它里面的集合,所存储的元素就是不重复的,通过元素的equals方法,来判断是否为重复元素. HashSet存储JavaAPI中的类型元素 给HashSet中存储JavaAPI中提供的类型元 ...

  9. Python 学习笔记(十二)Python文件和迭代(一)

    文件 文件和文件夹 文件:文本文件.二进制文件 文件夹:(windows) G:\pythonWorkspace\python\study (linux/mac) /home/workspace/py ...

  10. ConfigurationManager.AppSettings方法

    一 配置文件概述: 应用程序配置文件是标准的 XML 文件,XML 标记和属性是区分大小写的.它是可以按需要更改的,开发人员可以使用配置文件来更改设置,而不必重编译应用程序.配置文件的根节点是conf ...