本文摘录于http://blog.csdn.net/socoolfj/archive/2006/05/23/750425.aspx,并修改例子的代码,加上自己的见解。
类装载步骤
在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下:
装载:查找和导入类或接口的二进制数据;
链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;
校验:检查导入类或接口的二进制数据的正确性;
准备:给类的静态变量分配并初始化存储空间;
解析:将符号引用转成直接引用;
初始化:激活类的静态变量的初始化Java代码和静态Java代码块。
其中 初始化(initialization)包含两部分:
1.类的初始化(initialization class & interface)
2.对象的创建(creation of new class instances)。
因为类的初始化其实是类加载(loading of classes)的最后一步,所以很多书中把它归结为“对象的创建”的第一步。其实只是看问题的角度不同而已。为了更清楚的理解,这里还是分开来。
顺序:
因为类的加载肯定是第一步的,所以类的初始化在前。大体的初始化顺序是:
类初始化 -> 子类构造函数 -> 父类构造函数 -> 实例化成员变量 -> 继续执行子类构造函数的语句
下面结合例子,具体解释一下。
1. 类的初始化(Initialization classes and interfaces)
其实很简单,具体来说有:
(a)初始化类(initialization of class),是指初始化static field 和执行static初始化块。
  1. public class Demo{
  2. //初始化static field,
  3. //其中= "initialization static field"又叫做static field initializer
  4. private static String str = "initialization static field";
  5. //初始化块,又叫做static initializer,或 static initialization block
  6. static {
  7. System.out.println("This is static initializer");
  8. }
  9. }
btw,有些书上提到static initializer 和 static field initializer 的概念,与之对应的还有 instance initializer 和 instance variable initializer。例子中的注释已经解释了其含义。
(b)初始化接口(initialization of interface),是指初始化定义在该interface中的field。
*注意*
1. initialization classes 时,该class的superclass 将首先被初始化,但其实现的interface则不会。
initialization classes 时,该class的superclass,以及superlcass的superclass 会首先被递归地初始化,一直到java.lang.Object为止。但initialiazation interface的时候,却不需如此,只会初始化该interface本身
2. 对于由引用类变量(class field)所引发的初始化,只会初始化真正定义该field的class。
3. 如果一个static field是编译时常量(compile-time constant),则对它的引用不会引起定义它的类的初始化。
为了帮助理解最后两点,请试试看下面的例子:
Initialization类
  1. public class Initialization {
  2. static {
  3. System.out.println("Initialization Main class");
  4. }
  5. public static void main(String[] args)  {
  6. System.out.println(Sub.y);
  7. System.out.println(Sub.x);
  8. System.out.println(Sub.z);
  9. }
  10. }
Sub类
  1. public class Sub extends Super {
  2. public static final int y = 2005;
  3. public static int z;
  4. static {
  5. System.out.println("Initialization Sub");
  6. }
  7. }
Super类
  1. public class Super {
  2. public static int x = 2006;
  3. static {
  4. System.out.println("Initialization Super");
  5. }
  6. }
输入结果
Initialization Main class
2005
Initialization Super
2006
Initialization Sub
0

从这个结果可以看到,
1. static块在类中会先执行;(实际上是先加载static成员变量,然后是static代码块)
2. static 的final变量不会引起类的初始化;
3. 子类Sub引用父类Super里面的变量,就会引起父类的初始化,但不会引起子类的初始化;
4. static的成员变量也有默认值。
2. 对象的创建(creation of new class instances)
看例子来说明:
InitializationOrder类
  1. public class InitializationOrder {
  2. public static void main(String[] args) {
  3. SubClass sb = new SubClass();
  4. }
  5. }
SuperClass类
  1. public class SuperClass{
  2. static {
  3. System.out.println("SuperClass static");
  4. }
  5. SuperClass(String str){
  6. System.out.println(str);
  7. }
  8. }
Interface类
  1. interface Interface{
  2. static SuperClass su = new SuperClass("Interface new SuperClass");
  3. }
SubClass类
  1. public class SubClass extends SuperClass implements Interface{
  2. static {
  3. System.out.println("SubClass static");
  4. }
  5. private SuperClass su = new SuperClass("initialization variable");
  6. SubClass() {
  7. super("super");
  8. new SuperClass("new SuperClass");
  9. }
  10. }
输出结果
SuperClass static
SubClass static
super
initialization variable
new SuperClass
解释一下:
1) Java虚拟机要执行InitializationOrder类中的static 方法main(),这引起了类的初始化。开始初始化InitializationOrder类。具体的步骤略去不说。
2) InitializationOrder类初始化完毕后,开始执行main()方法。语句SubClass sb = new SubClass()将创建一个SubClass对象。加载类SubClass后对其进行类初始化,因为Subclass有一个父类SuperClass,所以先初始化SuperClass类。于是看到输出“SuperClass static”。
3) SuperClass类初始化完毕后,开始初始化SubClass类,输出“SubClass static”。
4) 至此,类的加载工作全部完成。开始进入创建SubClass的对象过程。先为SubClass类和其父类SuperClass类分配内存空间,这时Super su 被赋值为null。
5) 执行构造函数SubClass(),执行super(), 调用父类的构造函数,输出“super”。
6) 初始化SubClass类的成员变量su,输出“initialization variable”。
7) 继续执行构造函数的剩余部分,执行new SuperClass("new SuperClass"),输出“new SuperClass”,这时Super su 被赋值新建对象的引用
8) 而SubClass虽然实现了接口Interface,但是初始化它的时候并不会引起接口的初始化,所以接口Interface中的static SuperClass su = new SuperClass("Interface new SuperClass")自始至终都没有被执行到。
所以对象的创建,具体步骤如下:
(1) 所有的成员变量—包括该类,及它的父类中的成员变量--被分配内存空间,并赋予默认值。(这里是第一次初始化成员变量)
(2) 为所调用的构造函数初始化其参数变量。(如果有参数)
(3) 如果在构造函数中用this 调用了同类中的其他构造函数,则按照步骤(2)~(6)去处理被调用到的构造函数。
(4) 如果在构造函数中用super调用了其父类的构造函数,则按照步骤(2)~(6)去处理被调用到的父类构造函数。
(5) 按照书写顺序,执行instance initializer 和 instance variable initializer来初始化成员变量。(这里是第二次初始化成员变量)
(6) 按照书写顺序,执行构造函数的其余部分。
*******************
总结:
从类的初始化和对象的创建步骤,可以知道,一个类是先初始化static的变量和static句块,然后在分配该类以及父类的成员变量的内存空间,赋予默认值,然后开始调用构造函数。而子类和父类之间,则先初始化和创建父类,然后在初始化和创建子类的。
因此当我们引用类的static变量时,是没有分配该类以及父类的成员变量的内存空间的。

转载于:https://blog.51cto.com/android/384500

Java类和对象的初始化顺序相关推荐

  1. 解析 Java 类和对象的初始化过程

    跳转到主要内容 中国 [ 选择 ] dW 全部内容--------------  AIX and UNIX  Info Mgmt  Lotus  Rational  WebSphere-------- ...

  2. java类定义的顺序_Java类及对象的初始化顺序

    1.初始化规则: 下面规则优先级从前往后依次降低 0.加载一个类时先初始化基类后初始化扩展类: 1.类的初始化高于对象的初始化: 类的初始化依靠静态代码(被static标识的),静态代码块.静态变量这 ...

  3. java类编来那个初始化顺序_Java类及对象的初始化顺序

    1.初始化规则: 下面规则优先级从前往后依次降低 ①.加载一个类时先加载初始化基类后加载初始化扩展类: ②.类的初始化高于实例的初始化: 类的初始化依靠(静态代码块static{....})以及(静态 ...

  4. 解析 Java 类和对象的初始化过程 由一个单态模式引出的问题谈起

    在 IBM Bluemix 云平台上开发并部署您的下一个应用. 开始您的试用 问题引入 近日我在调试一个枚举类型的解析器程序,该解析器是将数据库内一万多条枚举代码装载到缓存中,为了实现快速定位枚举代码 ...

  5. Java类的各种成员初始化顺序

    初始化规则 1.父类[静态成员]和[静态代码块],按在代码中出现的顺序依次执行. 2.子类[静态成员]和[静态代码块],按在代码中出现的顺序依次执行. 3.父类的[普通成员变量被普通成员方法赋值]和[ ...

  6. Java类、实例的初始化顺序

    今晚是阿里巴巴 2013 校园招聘的杭州站笔试.下午匆忙看了两张历年试卷,去现场打了瓶酱油. 题目总体考察点偏基础,倒数第二题(Java 附加题)比较有趣,考察了 Java 初始化机制的细节,在此摘录 ...

  7. 解析 Java 类和对象的初始化过程(zhuang张 国建 (guojian.zhang@gmail

    [url]http://www.blogjava.net/rendong/default.html?page=2[/url]

  8. php键顺序初始化,Java类中各成员初始化的顺序

    了解Java中类各个成员的初始化顺序是非常重要的,这样你可以对类有全局的认识.不说太多,直接看下面的例子 class Father { static{ System. out.println(&quo ...

  9. java类中各成员初始化的顺序

    了解java中类各个成员的初始化顺序是非常重要的,这样你可以对类有全局的认识.不说太多,直接看下面的例子 class Father {static{System. out.println(" ...

最新文章

  1. Android--Otto事件总线 -- 组件之间通讯框架使用 --模式解析
  2. 多媒体容器格式概述①
  3. 大学课程重新学习-操作系统
  4. MyBatis 源码解读-pluginElement()
  5. 网络进阶:用了HTTPS就安全了吗?HTTPS 会被抓包吗?
  6. python随机生成k个不重复的随机数_使用Python生成不重复的随机值
  7. 页面常见跳转的方法和选择
  8. Python+Matplotlib绘制带误差线的柱状图
  9. 2018年秋计算机应用基础本科,广东开放大学远程教育专科2018年秋计算机应用基础Word模块测试...
  10. linux 快速合并文本文件,Linux-Linux中高效合并文本文件的方法
  11. 软件项目管理系统-进度编辑
  12. AVAudioPlayer 播放本地音乐
  13. misc 小小小试牛刀
  14. 大数据工程师必备之数据可视化技术
  15. 怎么删除win10 C盘Hiberfil.sys文件,Hiberfil.sys文件删了有没有事?
  16. IoTF 2021第七届中国国际物联网博览会
  17. 妹子图APP(四)—— SQLite保存数据实现离线图片查看
  18. Python读取显示raw图片+numpy基本用法记录
  19. 正式加入阿里巴巴!跟Android初学者分享几点经验,附超全教程文档
  20. android车载系统测试,【图】原生安卓来了!Polestar 2智能车联测试_汽车之家

热门文章

  1. SVM算法在项目实践中的应用!
  2. 美观实用!Star 过万,用 Python 做交互式图形的这款工具火了!
  3. 学术会议,已沦为表演...
  4. PyTorch 1.8来了!正式支持AMD GPU,炼丹不必NVIDIA
  5. 涵盖18+ SOTA GAN实现,这个图像生成领域的PyTorch库火了
  6. 奥巴马竟被「去马赛克 AI」洗白,CVPR 新研究惹上种族歧视大麻烦,LeCun 也被卷入其中...
  7. 清华学霸直博简历火了!CPU、操作系统、编译器全自主写,刘知远点赞
  8. MySQL数据库中as和distinct关键字
  9. celery的初次使用
  10. 汇编语言 利用and运算 将字符串中的某个字母变成大写