一、误区:简单认为JAVA静态代码块在类被加载时就会自动执行。证错如下:

  1. class MyClass1 {
  2. static {//静态块
  3. System.out.println("static block ");
  4. }
  5. }
  6. public class Main {
  7. Class[] classArray = {
  8. MyClass1.class//这样引用该类,必然需要将该类加载到虚拟机中
  9. };
  10. public static void main(String[] args){
  11. System.out.println("hello word");
  12. }
  13. }

执行结果:并没有输出" static bolck"

二、正解: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虚拟机》

java的static块执行时机的更多相关文章

  1. Java中static块执行时机

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

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

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

  3. java static代码块执行时机

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

  4. java finally块执行时机分析

    java里 finally 关键字通常与try catch块一起使用.用来在方法结束前或发生异常时做一些资源释放的操作.最近也看到网上有一些讨论try catch finally关键词执行的顺序的文章 ...

  5. java的static块及相关内容

    原文地址:http://blog.csdn.NET/lubiaopan/article/details/4802430     感谢原作者! static{}(即static块),会在类被加载的时候执 ...

  6. java static{}块

    java中static{}块只有在类加载是才会被调用. 这说明:static只有可能被调用一次. 原因:首先理解什么是类加载,区分类加载和申明对象的区别. public class StaticTes ...

  7. [java基础]java中static关键字

    1.static概念 static是静态修饰符,什么叫静态修饰符呢?大家都知道,在程序中任何变量或者代码都是在编译时由系统自动分配内存来存储的,而所谓静态就是指在编译后所分配的内存会一直存在,直到程序 ...

  8. java中static作用详解

    static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static修饰的成员变量和成员方法独立于该类的任何 ...

  9. Java中static关键字的作用和用法详细介绍

    static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念. 被static修饰的成员变量和成员方法独立于该类的任何 ...

随机推荐

  1. [解决方案]在Sql Server 2008/2005 数据库还原出现 3154错误

    在Sql Server 2008/2005 数据库还原出现 3154错误 解决方法1:不要在数据库名字上点右键选择还原,而要是在根目录“数据库”三个字上点右键选择还原,然后再选择数据库,问题便可以解决 ...

  2. title与h1的区别

    title与h1的联系: 从网站角度看,title更重于网站信息.title可以直接告诉搜索引擎和用户这个网站是关于什么主题和内容的. 从文章角度看,h1则是用于概括文章主题.用户进入内容页,想看到的 ...

  3. HighCharts 详细使用及API文档说明

    一.HighCharts开发说明: HighCharts开发实际上配置HighCharts每个部分,比如配置标题(title),副标题(subtitle)等,其中每个部分又有更细的参数配置,比如标题下 ...

  4. react native 底部按钮切换

    在react   native  中底部按钮的切换  主要的是运用的是<TabBarNavigator/>这个组件,具体的代码实现如下: render() { return ( <T ...

  5. System.Web.HttpRequestValidationException——从客户端检测到危险的Request值

    这是比较常见的问题了,如果Web表单中有输入类似于Html标签之类的文本,在通过Request.QueryString或者Request.Form传递这些值的时候,就会触发这样的异常,出于脚本注入等安 ...

  6. MemCached配置与缓存知识概述

    先看看百度百科里面对缓存的介绍: 缓存(Cache memory)是硬盘控制器上的一块内存芯片,具有极快的存取速度,它是硬盘内部存储和外界接口之间的缓冲器.由于硬盘的内部数据传输速度和外界介面传输速度 ...

  7. ListView缓存机制踩过的坑

    ListView,GrildView使用时候经常会用到缓存机制,随意一搜,例子成千上万,但是讲解都是很一致,跟自己踩的坑很少有人讲解到. 测试 需求: GrildView 分三列显示,默认背景为白色, ...

  8. Java系列:国际化(zz)

    国际化英文单词为:Internationalization,又称I18N,I为因为单词的第一个字母,18为这个单词的长度,而N代表这个单词的最后一个字母.国际化又称本地化(Localization,L ...

  9. js浮点数精确计算(加、减、乘、除)

    <SPAN style="FONT-SIZE: 18px">//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显.这个函数返回较为精确的加 ...

  10. swift第二季高级语法

    一.类和结构体 二.属性 三.方法 四.下标 五.继承和扩展 六.初始化和反初始化