锁定老帖子 主题:Java代码执行顺序分析
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-12-22
最后修改:2010-12-28
版权声明:这个系列的文章都是看了别人的文章有感而发创作的,所谓"知识没有抄袭之说",如果有人发现雷同或属巧合或属非巧合,不过不过本人绝对不屑copy然后paste的勾当,那样只会产生信息的冗余。 朋友们装载请记得注明出处!
记得胡哥曾经说过,想弄懂新的技术点有两条路:一 自己假设然后验证然后调整你的假设再验证;二 看别人现成的然后记住。今天我选了第一条路来挖掘“Java代码的执行顺序”这个主题的东东。
第一步:初步测试 静态块、普通块、静态方法、main方法、构造函数执行顺序。
Exm1-Exm8 所有源码见附件!
Main方法在父类中:
Exm1:子类在父类的内部console:
Exm2:子类在父类外部console:
Main方法在子类中:
Exm3:子类在父类内部console:
Exm4:子类在父类外部console:
Main方法在第三方类中:
Exm5:子类在父类外部console:
测试静态方法
Exm6:mian方法在子类中console:
分析实验结果:
1、先加载先加载静态部分,后加载非静态部分。(注意main是静态方法) 2、调用构造函数的时候:先父后子;先执行独立的非静态代码块,后执行构造方法。 3、Main方法总是等加载完本类的静态方法之后执行。 4、如果main方法中有方法调用非main方法所在类中的构造函数,执行的顺序将是: 从最‘老’的父类开始,先加载完所有static block ,然后才是最‘老’父类的构造函数。
如果要我总结:
1、方法、块对应静态和普通两个级别,如果不产生实例,就只执行静态部分,所有关联类中的静态部分总先于非静态部分执行。 2、静态部分中再分:静态块先于静态方法。非静态部分中构造函数再分:父类先于子类。(非静态部分中的方法,构造函数也没什么特别,构造函数和普通函数的却别就是super父类方法而已)
如果要我加上静态变量:
Exm7:Dog类有两个int 、Poddle两个类型静态变量console:
并没有违背我上面总结的两点,无非就是静态变量的实例化在所有静态块之前。
--------------------第二步:大胆猜测 ----------------
JVM将静态的(属性、方法、独立块)和非静态的分开处理。 鉴于JVM有类加载和实例化两个阶段。我大胆猜测,所有静态部分属于类加载阶段,所有非静态部分属于实例化阶段。而类加载总是先于实例化的。 类加载阶段分两步: 1、找到main方法中所在类静态属性,如果'new'了就实例化,如果是基本数据类型有赋值就用,否则用缺省值。 2、找到main方法中所在类的静态块执行。 -----------------------------main方法分割线---------------------------------------------- 3、从找到第一个构造函数。(不一定在main方法中声明,也许通过外部方法调用) 4、找到构造函数对应类的继承体系,加载所有静态属性和静态块(如果之前已经加载将不重复加载)。然后从最初的类开始调用构造函数(调用构造函数之前会执行普通独立块)。(如果这一步不是构造函数是静态方法,将按同样的顺序加载静态部分) 5、找到下一个构造函数,如果找到,返回第4步;如果没找到,结束。
测试我的猜想:
Exm8:console: exe static block in Poddle! exe common block in Dog! exe Dog contructor! exe common block in Poddle! exe Poddle contructor! ---前五行加载main方法所在类中的静态属性 exe static block in Dog!
------------main方法分割线--------------
exe main method! i:10 s1:ssss s2:aaaa p:exe toString() in Poddle!--main方法 exe common block in Dog! exe Dog contructor! exe common block in Poddle! exe Poddle contructor!---实例化Poddle 类 exe static block in Shepherd_dog! exe common block in Dog! exe Dog contructor! exe common block in Shepherd_dog! exe Shepherd_dog contructor!---实例化Shepherd_dog类
--------------------------第三步:收工~~~----------
不要嫌我啰嗦,这次真的不多说了^-^:
PS:本文有误,现更正如下: 对单个类,JVM加载阶段(编译阶段): 1、给静态变量分配内存空间 2、用默认值初始化静态变量 3、按照静态变量和静态块的申明顺序执行初始化 4、如果创建对象;否则,直接结束 5、先给所有实例成员分配内存空间并用默认值初始化 6、按顺序执行实例块和变量 7、执行构造方法 如果是一个多类的应用程序,静态部部分只有在编译阶段生成类唯一的Class对象时加载一次。 并且,如果要创建子类对象,总是默认调用父类的无参构造器(除非显示调用父类构造器)。 因为如果父类的一些成员没有加载,直接加载子类根本不符合"父生子"的规律,并且实际上也 会引起混乱(如父类protected变量没有初始化,却在先加载子类是使用到了,到哪里去找呢? 内存中都还没有加载到?)
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-12-23
分析的精神值得赞赏
但是,当你看到了《深入java虚拟机》这一本书之后,你就都全明白了。 |
|
返回顶楼 | |
发表时间:2010-12-23
cantellow 写道 分析的精神值得赞赏 但是,当你看到了《深入java虚拟机》这一本书之后,你就都全明白了。 跟楼上一样,推荐你看《深入Java虚拟机》 ps:不知道为啥那么多人说这本书翻译的差 起初看的时候有同感,后来发现这本书翻译得无比好 |
|
返回顶楼 | |
发表时间:2010-12-23
cantellow 写道 分析的精神值得赞赏
但是,当你看到了《深入java虚拟机》这一本书之后,你就都全明白了。 呵呵~我也明白看别人的书会学的快,不过有的时候自己分析分析也是种乐趣。 |
|
返回顶楼 | |
发表时间:2010-12-23
最后修改:2010-12-23
liaofeng_xiao 写道 cantellow 写道 分析的精神值得赞赏
但是,当你看到了《深入java虚拟机》这一本书之后,你就都全明白了。 跟楼上一样,推荐你看《深入Java虚拟机》 ps:不知道为啥那么多人说这本书翻译的差 起初看的时候有同感,后来发现这本书翻译得无比好 曹晓刚看到的话,肯定不是滋味吧。 另,其实我根本没看完LZ写的什么,因为你的排版实在不敢恭维。 |
|
返回顶楼 | |
发表时间:2010-12-23
liaofeng_xiao 写道 cantellow 写道 分析的精神值得赞赏
但是,当你看到了《深入java虚拟机》这一本书之后,你就都全明白了。 跟楼上一样,推荐你看《深入Java虚拟机》 ps:不知道为啥那么多人说这本书翻译的差 起初看的时候有同感,后来发现这本书翻译得无比好 看第一遍确实觉得很难受,看第二遍第三遍就好多了 |
|
返回顶楼 | |
浏览 8143 次