Java的静态代码块是否会在类被加载时自动执行?
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类加载的过程
- 装载
- 连接
- 初始化
其中装载阶段又三个基本动作组成:
- 通过类型的完全限定名,产生一个代表该类型的二进制数据流
- 解析这个二进制数据流为方法区内的内部数据结
- 构创建一个表示该类型的java.lang.Class类的实例
另外如果一个类装载器在预先装载的时遇到缺失或错误的class文件,它需要等到程序首次主动使用该类时才报告错误。
连接阶段又分为三部分:
- 验证,确认类型符合Java语言的语义,检查各个类之间的二进制兼容性(比如final的类不用拥有子类等),另外还需要进行符号引用的验证。
- 准备,Java虚拟机为类变量分配内存,设置默认初始值。
- 解析(可选的) ,在类型的常量池中寻找类,接口,字段和方法的符号引用,把这些符号引用替换成直接引用的过程。
当一个类被主动使用时,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的静态代码块是否会在类被加载时自动执行?的更多相关文章
- Java误区: 静态代码块,当把类将被载入到自己主动运行?
JAVA静态代码块会在类被载入时自己主动运行? 非常多Java开发人员的思想,被这个思想深深的轮奸了n遍,传播这个错误思想的博客,在网上一堆,越来越多的人被轮奸. 如:http://blog.csdn ...
- java的静态代码块和类变量的隐式覆盖
静态代码块特点:随着类的加载执行一次,且仅会执行一次 作用:初始化类中的static修饰的变量(static修饰的变量称为类变量.类变量和静态代码块差不多,类变量仅会被初始化一次) 一.静态代码块写法 ...
- java中静态代码块详解
感谢大佬:https://blog.csdn.net/qq_35868412/article/details/89360250 今天在项目中看到这行代码,静态代码块,很久没用静态代码块了,今天来复习一 ...
- Java 中静态代码块初始化问题测试
Java 中静态代码块初始化问题测试 原创 情况一:变量是 static final 修饰的"编译期常量",如 public static final String a = &qu ...
- java中静态代码块,非静态代码块,构造函数
关于静态代码块 静态代码块的写法: static { System.out.println("我是静态代码块"); } 静态代码块的特点: 1.执行优先级高于非静态的初始化块,它会 ...
- Java之同步代码块处理继承Thread类的线程安全问题
package com.atguigu.java; /** *//** * 使用同步代码块解决继承Thread类的方式的线程安全问题 * * 例子:创建三个窗口卖票,总票数为100张.使用继承Thre ...
- (转)java中静态代码块的用法 static用法详解
一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来 ...
- java中静态代码块的用法 static用法详解(转)
(一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序 ...
- 【转】java中静态代码块的用法 static用法详解
原文网址:http://www.cnblogs.com/panjun-Donet/archive/2010/08/10/1796209.html (一)java 静态代码块 静态方法区别一般情况下,如 ...
随机推荐
- Linux下RabbitMq安装
在大多数大公司,像应用服务器软件的安装.部署都是运维的事情,其实自己去尝试部署一下,也是有收获的. 有机会正好尝试了Linux下的rabbitMq安装过程,做了记录,希望有用到的人可以做下参考. 安装 ...
- QGIS1.8.0的编译
很早就关注QGIS了,关于它的编译,也尝试了好几次,但都没有成功.在要放弃的时候,再尝试了一回,完全按照他的intall指导.终于成功. 择其要点而言,就是要按部就班,不能偷工减料.想要成功编译,请按 ...
- 翻煎饼 Stacks of Flapjacks
题意:本题意为煎饼排序,大的放在上面,小的放在下面(此题输入是从上到下输入的),为煎饼排序是通过一系列的"翻转"动作来完成的.翻转动作就是将一个小铲插到一叠煎饼中的某两个煎饼之间, ...
- 浏览器正确理解和使用GBK及UTF-8(UTF-8 + BOM)网页编码
网页编码英文译为web page encoding.是在网页中指定其特定的字符编码格式的库. GBK是国家标准GB2312基础上扩容后兼容GB2312的标准. GBK的文字编码是用双字节来表示的.即不 ...
- map对象拷贝问题
map对象赋值: HashMap<String,Object> hm = new HashMap(); HashMap<String,Object> hmCopy = new ...
- mybatis插入实体到数据库后获取自增的主键
话不多说,直接说方法. 1.在insert语句中加入如下的代码. <insert id="insertSelective" parameterType="com.q ...
- python 列表解析
列表解析,主要用于动态创建列表 本篇主要说一下,lambda.map().和filter()同列表解析语句之间结合的用法 列表解析的基本语法为:[expr for iter_var in iterab ...
- js复制链接
需求:js复制一个并非当前页面的链接 实现: html <button class="btn btn-primary btn_copyurl">复制课程链接</b ...
- Linux服务器配置(一)
Linux服务器配置(一) jdk,tomcat,nginx记录 最近公司买了三台服务器System x3650 M5用来跑公司的项目.现,记录一下真机部署与后期维护历程~ 因为系统是服务器买来就装好 ...
- Intellij IDEA编译代码出现红色标志
如图 原因:项目没有模块化加载 解决方法: 快捷键 Ctrl+Alt+Shift+S 进入 Project Structure 界面,选择 Modules --> Sources -->选 ...