java项目包创建顺序_java程序初始化的顺序
来自:http://blog.csdn.net/socoolfj/article/details/750425 http://www.cnblogs.com/miniwiki/archive/2011/03/25/1995615.html
规则1(无继承情况下):对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是
(静态变量、静态初始化块)>(变量、初始化块)>构造器
规则2(有继承情况下):子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成。静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
总结:先静后动,先父后子,从上到下,先变量后构造
原理:
初始化(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初始化块。
例如:class Super {
static String s = “initialization static field”; //初始化static field,其中“= “initialization static field” ”又叫做static field initializer
// static初始化块,又叫做static initializer,或 static initialization block
static {
System.out.println(“This is static initializer”);
}
}
btw,有些书上提到static initializer 和 static field initializer 的概念,与之对应的还有 instance initializer 和 instance variable initializer。例子中的注释已经解释了其含义。
(b)初始化接口(initialization of interface),是指初始化定义在该interface中的field。
*注意*
--initialization classes 时,该class的superclass 将首先被初始化,但其实现的interface则不会。
--initialization classes 时,该class的superclass,以及superlcass的superclass 会首先被递归地初始化,一直到java.lang.Object为止。但initialiazation interface的时候,却不需如此,只会初始化该interface本身。
--对于由引用类变量(class field)所引发的初始化,只会初始化真正定义该field的class
--如果一个static field是编译时常量(compile-time constant),则对它的引用不会引起定义它的类的初始化。
class Super{
static int x = 2006
}
class Sub extends Super {
static final int y = 2005;
static int z;
static {
System.out.println("Initialization Sub");
}
}
public class Initialization {
public static void main(String[] args) {
System.out.println(Sub.x); // Won't cause initialization of Sub, because x is declared by S, not Sub.
// 不会引起Sub类的初始化,因为x是定义在Super类中的
System.out.println("-------------------------");
System.out.println(Sub.y); // Won't cause initialization of Sub, because y is constant.
// 不会引起Sub类的初始化,因为y是常量
System.out.println("-------------------------");
System.out.println(Sub.z = 2004); // Will cause initialization of Sub class
// 将会引起Sub的初始化
}
}
2.对象的创建(creation of new class instances)
(a) 所有的成员变量—包括该类,及它的父类中的成员变量--被分配内存空间,并赋予默认值。(Btw,这里是第一次初始化成员变量)
(b) 为所调用的构造函数初始化其参数变量。(如果有参数)
(c) 如果在构造函数中用this 调用了同类中的其他构造函数,则按照步骤(b)~(f)去处理被调用到的构造函数。
(d) 如果在构造函数中用super调用了其父类的构造函数,则按照步骤(b)~(f)去处理被调用到的父类构造函数。
(e) 按照书写顺序,执行instance initializer 和 instance variable initializer来初始化成员变量。(Btw,这里是第二次初始化成员变量)
(f) 按照书写顺序,执行constructor的其余部分。
*注意*
成员变量其实都被初始化2次,第一次是赋予默认值,第二次才是你想要设定的值。
最后看一个例子:
class Super{
static {
System.out.println(1);
}
Super(int i){
System.out.println(i);
}
}
class Subclass extends Super implements Interface{
static {
System.out.println(2);
}
Super su = new Super(4);
Subclass() {
super(3);
new Super(5);
}
}
interface Interface{
static Super su = new Super(0);
}
public class InitializationOrder {
public static void main(String[] args) {
Subclass sb = new Subclass();
}
}
稍微解释一下:
首先,Java虚拟机要执行InitializationOrder类中的static 方法main(),这引起了类的初始化。开始初始化InitializationOrder类。具体的步骤略去不说。
接着,InitializationOrder类初始化完毕后,开始执行main()方法。语句Subclass sb = new Subclass()将创建一个Subclass对象。加载类Subclass后对其进行类初始化,但因为Subclass有一个父类Super,所以先初始化Super类,初始化块static {System.out.println(1);}被执行,打印输出1;
第三,Super初始化完毕后,开始初始化Subclass类。static {System.out.println(2);}被执行,打印输出2;
第四,至此,类的加载工作全部完成。开始进入创建Subclass的对象过程。先为Subclass类和其父类Super类分配内存空间,这时Super su 被附值为null;
第五,执行构造函数Subclass()时,super(3)被执行。如前面(d)所说,Super类的构造函数Super(int i){….}被调用,并按照步骤(b)~(f)来处理。因此,递归调用Super类的父类Object类的构造函数,并按照步骤(b)~(f)来初始化Object类,不过没有任何输入结果。最后打印输出3;
第六,如前面(e)所说,初始化成员变量su,其结果是打印输出4;
第七,如前面(f)所说,执行new Super(5),并打印输出5;
最后,Subclass虽然实现了接口Interface,但是初始化它的时候并不会引起接口的初始化,所以接口Interface中的static Super su = new Super(0)自始至终都没有被执行到。
① 类属性 (静态变量) 定义时的初始化,如上例的 static String a = "string-a";
② static 块中的初始化代码,如上例 static {} 中的 b = "string-b";
③ 对象属性 (非静态变量) 定义时的初始化,如上例的 String c = "stirng-c";
④ 构造方法 (函数) 中的初始化代码,如上例构造方法中的 d = "string-d";
java项目包创建顺序_java程序初始化的顺序相关推荐
- java项目怎样提高性能_Java程序员成长之路(如何提高Java程序性能?)
1.尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面 第一,控制资源的使用,通过线程同步来控制资 ...
- java程序初始化_Java程序初始化顺序
今天在课上复习了Java的初始化顺序,一直有点疑惑,搞不明白,所以打算写下来,记录一下. 先说一下Java程序初始化的顺序:父类静态变量>父类静态代码块>子类静态变量>子类静态代码块 ...
- 如何用eclise创建java项目到创建包到创建类?
Eclise创建java项目到创建包到创建类流程 第一步: ① 打开eclise ② 点击New ③ 点击Project... 第二步: ① 选中Java Project ② 点击Next 进行下一步 ...
- java成员初始化顺序_Java成员初始化顺序
1. 初始化顺序 在类的内部,变量定义的先后顺序决定了初始化的顺序.即使变量散布于方法定义之间,他们仍会在任何方法(包括构造器)被调用之前初始化. 2. 静态成员初始化顺序 1⃣️初始化类的静态成员或 ...
- java项目制作成可安装exe程序
java项目制作成可安装exe程序 文章目录 java项目制作成可安装exe程序 1.制作可安装的exe程序步骤 2. IDEA项目导出jar包 2.1. 打开project Structure 2. ...
- 56.java编程思想——创建窗口和程序片 用户接口API
56.java编程思想--创建窗口和程序片 用户接口API Java 1.1 版同样增加了一些重要的新功能,包括焦点遍历,桌面色彩访问,打印"沙箱内"及早期的剪贴板支持. 焦点遍历 ...
- idea 新建的java项目没发run_IntelliJ IDEA创建普通的Java 项目及创建 Java 文件并运行的教程...
最近突然看到这篇几年前随手记录的文章,居然浏览量那么高.看来很多小伙伴也开始从 Eclipse 转到 IDEA,这里为了让大家更好的掌握 IDEA 的使用,我建议大家可以看看下面这个 IDEA 教程. ...
- 56 java编程思想 创建窗口和程序片 用户接口API
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 56.j ...
- 57 java编程思想 创建窗口和程序片 可视编程和Beans
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 57.j ...
最新文章
- Halide应用开发
- Python : 什么是*args和**kwargs[转载]
- snipaste滚动截图方法_电脑必备!这个截图神器比QQ截图更好用
- CocoaPods 错误解决 Attempt to read non existent folder
- Java基础之this关键字和super关键字区别
- web开发常用工具介绍
- python @修饰符_数据结构与算法之8——抽象数据类型与python类
- xcode 自己常用到的快捷键
- 优化器,sgd,adam等
- Python飞机大战项目终篇(一步一步实现---最全笔记)
- Aspose.Cells 使用UnMerge()取消合并单元格(取消合并单行,取消合并单列,取消多行多列)
- 如何点亮或者关闭EMC VMAX的磁盘指示灯
- python统计元音字母个数_python统计并输出字符串中小写元音字母的个数?
- 数据科学之 如何找到指标的最 佳分裂点的几个想法
- android仿微信发送位置,Android仿微信发送位置-百度地图
- python bind绑定失败_Python tkinter之Bind(绑定事件)的使用示例
- java list转json报错_一个fastjson转换JSON字符串的报错排查
- java发送html模板的高逼格邮件
- 定义一个圆类Circle,成员变量:半径 radius;成员方法:构造方法、get和set半径的方法、计算面积和周长的方法。
- java入口函数_Java 函数入口