今天看到一个关于类加载与初始化顺序的一个例子,虽然有点怪,但懂了真的很有意思,也能反应出理解的深度,还是先看代码吧

public class StaticTest
{public static void main(String[] args){staticFunction();}static StaticTest st = new StaticTest();//第9行static{System.out.println("1");}{System.out.println("2");}StaticTest(){System.out.println("3");System.out.println("a="+a+",b="+b);}public static void staticFunction(){System.out.println("4");}static int b = 112;//第27行int a = 110;}

各位,能看出输出结果么,结果是

2
3
a=110,b=0
1
4

我相信很多人都和我开始一样没看懂为啥静态变量b输出0,而非静态变量a是110。不慌,往下看。

概念

静态初始化:在使用到类的任意元素时初始化,对内部的静态变量,静态块进行执行,并且按照程序给定顺序(不论是块还是成员变量),只此一次

实例初始化:在调用构造方法时初始化,对类中非静态成员变量初始化,执行构造块(没有只此一次)

程序执行步骤

这里设计到的关键步骤在于准备初始化两个阶段

程序入口位于main方法,main方法在StaticTest类中,所以开始静态初始化staticTest类

当执行到第9行也就是

    static StaticTest st = new StaticTest();//第9行

时,因为需要构造实例,所以在静态初始化的半路又跑去执行实例初始化去了

实例初始化先后执行了构造块输出了2, 然后对a赋了值,再去执行构造函数(这时候b还没有赋值!!!!!),输出a=110,b=0。实例初始化结束

继续执行没执行完的静态初始化,输出静态块中的1,给b赋值112,静态初始化结束

最后输出main中的4,程序结束

再度分析

问:为什么b是0?

答:最关键的是在于内嵌初始化,这里的静态初始化中途又加了一个实例初始化,蛋疼的是b的赋值还在该实例初始化之后,在准备阶段分配空间时大家都有默认值,基本数值类型是0,引用是null,所以b默认值是0,实例化时输出的也是0

问:实例初始化中途使用到未被赋值的静态变量,该变量不会去赋值吗?

答:首先静态初始化肯定在实例初始化之前,这里是静态初始化中途遇到需要实例初始化的静态变量,所以才去调用

的实例初始化,实例初始化会觉得用到的静态变量已经被赋了值了,它便不再去管静态变量的值是否是默认值还是已经赋了

值,所以不会去给未被赋值的静态变量赋值

程序改动

改动1:把static int b = 112;放到第九行之前,也就是说把b的赋值放到内嵌的实例初始化之前,结果中b=112,说明确实是顺序问题导致b没被赋值

改动2:或者把main方法中的StaticFunction()改成new StaticTest(),这时的b输出为112,进一步证明内嵌了实例初始化过程,实例初始化结束后最终完成未完成的静态初始化(b赋值112),再执行的main方法,这一次输出的a=110,b=112

关于类加载详细信息,可以看http://blog.csdn.net/u013256816/article/details/50829596

Java类加载与初始化机制实例分析相关推荐

  1. 关于Java类加载双亲委派机制的思考(附面试题)

    转载自 关于Java类加载双亲委派机制的思考(附面试题) 预定义类加载器和双亲委派机制 JVM预定义的三种类型类加载器: 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 &l ...

  2. java程序的运行机制详细分析

    转自:http://hi.baidu.com/suny_duan/blog/item/074f9afb09f08c9b58ee901b.html JVM(Java虚拟机)一种用于计算设备的规范,可用不 ...

  3. java类加载机制为什么双亲委派_[五]类加载机制双亲委派机制 底层代码实现原理 源码分析 java类加载双亲委派机制是如何实现的...

    Launcher启动类 本文是双亲委派机制的源码分析部分,类加载机制中的双亲委派模型对于jvm的稳定运行是非常重要的不过源码其实比较简单,接下来简单介绍一下我们先从启动类说起有一个Launcher类 ...

  4. java filter 回调_Java 异步回调机制实例分析

    Java 异步回调机制 一.什么是回调 回调,回调.要先有调用,才有调用者和被调用者之间的回调.所以在百度百科中是这样的: 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用 ...

  5. Java系列笔记(1) - Java 类加载与初始化

    2019独角兽企业重金招聘Python工程师标准>>> 目录 类加载器 动态加载 链接 初始化 示例 类加载器 在了解Java的机制之前,需要先了解类在JVM(Java虚拟机)中是如 ...

  6. android 刷新view位置,Android View刷新机制实例分析

    本文实例讲述了Android View刷新机制.分享给大家供大家参考,具体如下: 一.总体说明 在Android的布局体系中,父View负责刷新.布局显示子View:而当子View需要刷新时,则是通知 ...

  7. java thread exit方法_实例分析Java终止线程和stop()方法

    Java终止线程实例和stop()方法源码阅读 了解线程 概念 线程 是程序中的执行线程.Java 虚拟机允许应用程序并发地运行多个执行线程. 线程特点 拥有状态,表示线程的状态,同一时刻中,JVM中 ...

  8. JAVA类加载与初始化顺序

    类的生命周期 7个阶段依次为:Loading Verification Preparation Resolution Initialization Using Unloading 类加载的双亲委派模型 ...

  9. 49天精通Java,第17天,Java类加载与初始化

    目录 专栏导读 一.类的加载与ClassLoader的理解 1.加载 2.链接 3.初始化 二.什么时候会发生类初始化 1.类的主动引用(一定会发生类的初始化) 2.类的被动调用(不会发生类的初始化) ...

最新文章

  1. software reporter tool占用高_广安市园林车载高射程雾炮机厂家供货
  2. 计算机一级考模拟试题,计算机一级MSOffice考前模拟试题「附答案」
  3. 【转载】SAP参数文件简介
  4. 25条写代码建议,句句真言,值得牢记!
  5. 术中导航_密码术中的计数器(CTR)模式
  6. javascript教程:console.log 详解
  7. 识别和追踪主题层次的影响力者(来自2018 Machine Learning 论文学习笔记)
  8. 老李推荐: 第3章2节《MonkeyRunner源码剖析》脚本编写示例: MonkeyDevice API使用示例 1...
  9. Python基础七(深浅copy以及int,str,tuple,list,dic补充)
  10. 机器学习数据特征归一化的目的及方式
  11. vant ,vue 图片上传压缩
  12. 语音搜索的基础-语音识别
  13. 一款基于tampermonkey的浏览器插件:聚合搜索
  14. 通过JavaScript中基于属性的TDD的钻石方块
  15. PostgreSQL 源码解读(31)- 查询语句#16(查询优化-表达式预处理#1)
  16. 华为ensp模拟器设备启动失败解决合集
  17. 优秀产品经理的18种能力
  18. 计算机的四屏故障维修,四则电脑显示器硬件故障检修实用技巧
  19. 《深入理解Java虚拟机》-周志明 -第3版-第一章摘记
  20. 易飞ERP单据自动审核程序

热门文章

  1. CodeForces 596C Wilbur and Points
  2. 常用模块(subprocess/hashlib/configparser/logging/re)
  3. clickhouse集群容器化搭建
  4. python多个函数_请教:一个类中可以定义多个同名函数?
  5. 手机收到回复TD退订的短信,需要回复吗?今天算是搞明白了
  6. [Eclips 安装] eclipse启动不了,出现“Java was...”如何解决
  7. 软件工程实验:原型设计
  8. cad计算机绘注意事项,CAD打印的基本操作和重要的注意事项
  9. 微信java tools_微信工具weixin-java-tools的使用总结
  10. 使用Xtext/Xtend 实现域专用语言DSL(2)