文档章节

java 中静态代码块执行的时机

职业搬砖20年
 职业搬砖20年
发布于 07/06 10:27
字数 746
阅读 5
收藏 4

1、简单认为JAVA静态代码块在类被加载时就会自动执行  是错误的


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");//执行结果:并没有输出" static bolck" 
    }
 
}

2、正解:static块真正的执行时机

一个类的运行分为以下步骤:

  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

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

© 著作权归作者所有

共有 人打赏支持
职业搬砖20年
粉丝 23
博文 205
码字总数 103975
作品 0
南京
程序员
Java和Android ClassLoder对比以及Class加载过程

Java的ClassLoder的父子关系如下:Bootstrap--ExtClassClassLoader---AppClassLoader。 JVM启动时先运行启动类加载器Bottstrap,主要加载Java核心API;然后加载扩展类加载器ExtClassLoder,该...

JasmineBen
05/23
0
0
Kotlin 设计模式解析之单例

单例模式介绍 单例模式是一个比较简单的设计模式,同时也是挺有意思的一个模式,虽然看起来简单,但是可以玩出各种花样。比如 Java 当中的懒饿汉式单例等。 什么是单例 单例模式的定义: En...

yonglan.whl
09/20
0
0
java静态/动态成员变量、初始化块,父类/子类构造函数执行顺序问题

/* * 几大原则 * 一、静态成员变量(Static) * 1、静态成员变量为类变量,所有对象共享同一内存空间 * 2、静态成员变量的声明和定义仅在首次加载类时执行一次 * 3、首次加载类时首先对所有静...

LCZ777
2014/08/25
0
0
12、Java并发性和多线程-Java同步块

以下内容转自http://ifeve.com/synchronized-blocks/: Java 同步块(synchronized block)用来标记方法或者代码块是同步的。Java同步块用来避免竞争。本文介绍以下内容: Java同步关键字(s...

easonjim
2017/06/15
0
0
【Java并发性和多线程】Java同步块

本文为转载学习 原文链接:http://tutorials.jenkov.com/java-concurrency/synchronized.html 译文链接:http://ifeve.com/synchronized-blocks/ Java 同步块(synchronized block)用来标记......

heroShane
2014/01/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周日乱弹 —— 小心着凉 @红薯

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子:5.33起,其声呜呜然,如怨如慕,如泣如诉。余音袅袅,不绝如缕。分享Arch Enemy的单曲《Bridge Of Destiny (2009)》 《Bridge Of...

小小编辑
今天
162
4
what f,,

anlve
今天
2
0
初级开发-编程题

` public static void main(String[] args) { System.out.println(changeStrToUpperCase("user_name_abc")); System.out.println(changeStrToLowerCase(changeStrToUpperCase("user_name_abc......

小池仔
今天
13
0
现场看路演了!

HiBlock
昨天
21
0
Rabbit MQ基本概念介绍

RabbitMQ介绍 • RabbitMQ是一个消息中间件,是一个很好用的消息队列框架。 • ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的s...

寰宇01
昨天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部