Java的静态代码块是否会在类被加载时自动执行?

摘要:
JAVA静态代码块将在加载类时自动执行?2.当使用java.lang.refect包的方法进行反射调用时,如果类未初始化,则需要对其进行初始化。3.初始化类时,发现其父类尚未初始化,因此需要初始化父类。4.当JVM启动时,需要首先初始化包含main方法的用户指定类。在初始化阶段,jvm主要完成静态变量的初始化和静态块的执行。因为false表示类在加载期间未初始化。
JAVA静态代码块会在类被加载时自动执行?

一、先看Java静态方法,静态变量

http://www.cnblogs.com/winterfells/p/7906078.html

静态代码块

在类中,可以将某一块代码声明为静态的,这样的程序块叫静态初始化段。静态代码块的一般形式如下:

static {
    语句序列
}
public class staticBlock{

        //定义一个普通的main()方法

        public static void main(String args[]){

        System.out.println("This is main method."); 

       }

      //定义一个静态代码块

     static{

         System.out.println("This is static block.");

         int stVar = 0;   //这是一个局部变量,只在本块内有效

      }

}

编译通过后,用java命令加载本程序,会得到如下输出:

This is static block.

This is main method.

从以上输出结果中可以看出,静态代码块甚至在main方法之前就被执行。在main()方法中可以完成的任务在静态代码块中都可以完成。但是二者在执行上仍然有一些区别,main方法是整个程序启动的入口,而静态代码块是存在于某个类中的一个过程。

那是不是只要类被加载了就一定会执行静态代码块?

二、再看JVM类加载的过程

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

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

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

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

    连接阶段又分为三部分:

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

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

  1. 遇到new, getstatic, putstatic 或者 invokestatic 4条字节码指令时,如果类没有进行过初始化,则需要先进行初始化。这些场景包括:使用new关键字实例化对象,读取或者设置一个类的静态字段以及调用一个类的静态方法的时候。

  2. 使用java.lang.reflect包的方法进行反射调用的时候,如果类没有初始化,需要进行初始化。

  3. 当初始化一个类的时候发现其父类还没有初始化,需要对父类进行初始化。

  4. JVM启动时,用户指定的包含main方法的那个类,需要首先进行初始化。

  5. JDK1.7中动态语言的支持,解析java.lang.invoke.MethodHandle的结果为REF_getStatic, REF_putStatic, REF_invokeStatic方法的句柄时,对应的类没有初始化的时候。

实际上,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块。

再看这个例子

class MyClass1 {
    static {//静态块
        System.out.println("static block ");
    }
}
public class Main {

    Class[] classArray = {
            MyClass1.class//这样引用该类,必然需要将该类加载到虚拟机中,(反射机制)
    };
    public static void main(String[] args){
        System.out.println("hello word");
    }

}

结果:

hello world

所以结论是不初始化则不会执行static块。

参考:《深入理解java虚拟机》

http://blog.csdn.net/jiese1990/article/details/40154329

http://www.cnblogs.com/ivanfu/archive/2012/02/12/2347817.html

免责声明:文章转载自《Java的静态代码块是否会在类被加载时自动执行?》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C#压缩指定的文件并生成zip文件C#去掉json字符串中的换行符下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

TensorFlow 编程基础

1、TensorFlow   安装:https://www.cnblogs.com/pam-sh/p/12239387.html      https://www.cnblogs.com/pam-sh/p/12241942.html • 是一个开放源代码软件库,用于进行高性能数值计算• 借助其灵活的架构,用户可以轻松地将计算工作部署到多种平台(CPU、G...

java08 数组与集合

1 数组的定义与规范 一个变量只能存放一个数据,一个数组是一个容器,可以存放多个数据 数组的特点 1 数组是一种引用数据类型 2 数组中的多个数据,类型必须统一 3 数组的长度在程序运行期间,不可改变 数组的初始化 1 动态初始化  指定长度:  数据类型[] 数组名称 = new数据类型 [ 数组长度] 左侧的数据类型  表示数组中保存的数据类型 左侧...

Linux动态频率调节系统CPUFreq之二:核心(core)架构与API

上一节中,我们大致地讲解了一下CPUFreq在用户空间的sysfs接口和它的几个重要的数据结构,同时也提到,CPUFreq子系统把一些公共的代码逻辑组织在一起,构成了CPUFreq的核心部分,这些公共逻辑向CPUFreq和其它内核模块提供了必要的API,像cpufreq_governor、cpufreq_driver等模块通过这些API来完成一个完整的CP...

HTTP,URL,FS 模块搭建一个静态WEB服务器

WEB服务器: 一般指网站服务器,是指驻留在因特网上某种类型计算机的程序,可以向浏览器等Web 客户端提供文档,也可以放置网站文件让全世界浏览,还可以放置数据文件,让全世界下载,目前最主流的Web服务器有 Apache,Nginx,IIS等。 NodeJS 创建一个WEB服务器, 可以让我们访问Web服务器上面的网站 可以让我们下载Web服务器上面的文件...

C语言 锁的使用总结

1. C 互斥锁 mutex初始化与去初始化 #include <pthread.h>int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);int pthread_mutex_destroy(pthread_mutex_t *mutex);...

生成静态页技术

生成静态页技术 概要: 1、什么是生成静态页技术?答:互联网上流行的做法是将数据源代码写入数据库再从数据库读取生成静态面,这样无形间就加大了数据库。将现有的ASP页直接生成静态页,将会节省很多。 2、为什么要生成静态页以及好处?答:一、加快页面打开浏览速度,静态页面无需连接数据库打开速度较动态页面有明 显提高; 二、有利于搜索引擎优化SEO,Baidu、...