Java程序执行流程分析
2017-07-03 00:17
344 查看
刚刚在复习JavaSE, 正好复习到 程序执行流程,所以写下这篇博客记录下
问题:一下这段代码的执行顺序
还是用图片好一点
![](https://img-blog.csdn.net/20170702233226466?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VpeGluXzM3NzIwOTA0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
我看到第一眼的答案是 先是main函数入口,第七行,再就是 第八行,再就是 第四行 然后 就第五行 再就是 第六行。 接下来我就发现我做不下去。
后来看了笔记想了想才知道我错了 。
main函数入口第七行开始这个肯定不会错,在往下走,第八行 这个时候new Test(); 调用了方法, 应该是直接去找方法 所以是第四行 也没错。接下来 往下 构造方法这里省略了一句 super();调用父类构造方法。当然这里父类是object 所以当做没有。 接下来呢 就是构造方法的特殊性了。 既然是构造方法 当然是要构造这个类啊, 就是要加载这个类的信息了,初始化一个类,必须先初始化它的属性 从第四行开始后, 就调到第二行加载这个类的属性 (至于为什么不是第一行而是第二行我也没想清楚,可能是因为第二行开始才是类的属性信息吧)再一直往下 第三行 直到把所有的这个类的属性加载完,在执行第五行,接着第六行。第六行执行完了以后才真正代表第八行执行完了,接下来就是第九行 一直到末尾
所以答案是 7 8 4 2 3 5 6 9 10 11
第二个例子: 是如下三段代码。 执行man函数输出什么结果
![](https://img-blog.csdn.net/20170702234436683?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VpeGluXzM3NzIwOTA0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
我不代码的执行步骤用换图的方式表示出来了
![](https://img-blog.csdn.net/20170702235242961?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VpeGluXzM3NzIwOTA0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
第一步:Java虚拟机肯定main函数入口的
第二步:main函数里面往下走, 调用T2的构造方法。
第三步:T2的构造方法,构造方法会调用父类T1的构造的方法super();
就到了T1的构造方法,T1的构造方法又super().T1的父类Test的构造方法
第四步:调用Test的构造方法,当然要调用super(); 就是object, 当做没有吧,之后就加载Test的属性
第五步:Test的属性加载
第六步:Test的属性加载
第七步:Test的属性加载完毕,Test构造方法完成。
第八步:Test这边完成就等于 T1构造方法中的super()完成,就下来就是加载T1的属性
第九步:T1的属性加载完成,就是继续完成自己的构造方法。
第十步:T1加载完成,也就是T2的构造方法中super()方法完成,就下来就是记载T2的属性
第十一步:完成自己的构造方法。
因此输出的信息为:
Test的属性
Test的构造方法
T1的属性
T1的构造方法
T2的属性
T2的构造方法
小小的总结:
程序加载第一步虚拟机肯定会找main函数 如果调用构造方法,那么构造方法 会先 加载父类的构造方法,再加载自己的属性。
看第三个例子
结果是:
father2
child2
father…
child…
father…
child…
18.0
我的理解是 把static内容分开,因为static是静态的 和非static内容不用,static可以看成一个 模具,非static 的内容都是根据static 复制出来的。所以相对于 “产品” 必须先有模具 而且模具 只有一套就够了。 因此statc的内容是最先输出来的。 而且是先父类再子类。 因为没有父类 子类的信息哪儿来? 怎么加载? 其他的就前面的类似了。。
问题:一下这段代码的执行顺序
public class Test { private String name="Jack"; private int age=2; public Test( ) { age=1000; //期望能到1000年 } public static void main(String [] args ) { Test t = new Test(); System.out.println(t.name + " " + t.age); } }
还是用图片好一点
我看到第一眼的答案是 先是main函数入口,第七行,再就是 第八行,再就是 第四行 然后 就第五行 再就是 第六行。 接下来我就发现我做不下去。
后来看了笔记想了想才知道我错了 。
main函数入口第七行开始这个肯定不会错,在往下走,第八行 这个时候new Test(); 调用了方法, 应该是直接去找方法 所以是第四行 也没错。接下来 往下 构造方法这里省略了一句 super();调用父类构造方法。当然这里父类是object 所以当做没有。 接下来呢 就是构造方法的特殊性了。 既然是构造方法 当然是要构造这个类啊, 就是要加载这个类的信息了,初始化一个类,必须先初始化它的属性 从第四行开始后, 就调到第二行加载这个类的属性 (至于为什么不是第一行而是第二行我也没想清楚,可能是因为第二行开始才是类的属性信息吧)再一直往下 第三行 直到把所有的这个类的属性加载完,在执行第五行,接着第六行。第六行执行完了以后才真正代表第八行执行完了,接下来就是第九行 一直到末尾
所以答案是 7 8 4 2 3 5 6 9 10 11
第二个例子: 是如下三段代码。 执行man函数输出什么结果
package com.obj; public class Test2 { public String s = "11111"; { System.out.println("Test的属性"); } public Test2(){ System.out.println("Test的构造方法"); } }
package com.obj; public class T1 extends Test2{ { System.out.println("T1的属性"); } public T1(){ super(); System.out.println("T1的构造方法"); } }
package com.obj; public class T2 extends T1{ { System.out.println("T2的属性"); } public T2(){ super(); System.out.println("T2的构造方法"); } public static void main(String[] args) { T2 t = new T2(); } }
我不代码的执行步骤用换图的方式表示出来了
第一步:Java虚拟机肯定main函数入口的
第二步:main函数里面往下走, 调用T2的构造方法。
第三步:T2的构造方法,构造方法会调用父类T1的构造的方法super();
就到了T1的构造方法,T1的构造方法又super().T1的父类Test的构造方法
第四步:调用Test的构造方法,当然要调用super(); 就是object, 当做没有吧,之后就加载Test的属性
第五步:Test的属性加载
第六步:Test的属性加载
第七步:Test的属性加载完毕,Test构造方法完成。
第八步:Test这边完成就等于 T1构造方法中的super()完成,就下来就是加载T1的属性
第九步:T1的属性加载完成,就是继续完成自己的构造方法。
第十步:T1加载完成,也就是T2的构造方法中super()方法完成,就下来就是记载T2的属性
第十一步:完成自己的构造方法。
因此输出的信息为:
Test的属性
Test的构造方法
T1的属性
T1的构造方法
T2的属性
T2的构造方法
小小的总结:
程序加载第一步虚拟机肯定会找main函数 如果调用构造方法,那么构造方法 会先 加载父类的构造方法,再加载自己的属性。
看第三个例子
public class Test2{ static int i=5; public static void main(String[] args){ Father father = new Child(); father = new Child(); System.out.println( (change()==3)?i+15:i+10.0 ); } public static int change(){ if(i==5){ i = i+10; } return i = i/5; } } class Father{ public Father(){ System.out.println("father..."); } static{ System.out.println("father2"); } } class Child extends Father{ public Child(){ System.out.println("child..."); } static{ System.out.println("child2"); } }
结果是:
father2
child2
father…
child…
father…
child…
18.0
我的理解是 把static内容分开,因为static是静态的 和非static内容不用,static可以看成一个 模具,非static 的内容都是根据static 复制出来的。所以相对于 “产品” 必须先有模具 而且模具 只有一套就够了。 因此statc的内容是最先输出来的。 而且是先父类再子类。 因为没有父类 子类的信息哪儿来? 怎么加载? 其他的就前面的类似了。。
相关文章推荐
- ndroid中的自动测试这里结合Music的测试程序,分析一下Android测试程序的结构和执行流程。
- Android程序的执行流程分析
- java再复习——代码执行的大体流程与内存分析
- Java虚拟机-Java程序执行流程
- Android OTA升级原理和流程分析(八)---升级程序update_binary的执行过程
- Java程序执行过程分析
- Android OTA升级原理和流程分析(八)---升级程序update_binary的执行过程
- Android程序的执行流程分析
- Dalvik虚拟机java方法执行流程和Method结构体分析
- 杰神之Java中的程序执行流程
- Java程序员从笨鸟到菜鸟之(四十)细谈struts2(四)struts2中action执行流程和源码分析
- Java多线程总结(6)— 线程池的基本使用和执行流程分析
- Java程序员从笨鸟到菜鸟之(四十)细谈struts2(四)struts2中action执行流程和源码分析
- Java 程序执行内存分析
- BioUsb-程序执行流程分析
- Java程序员从笨鸟到菜鸟之(四十)细谈struts2(四)struts2中action执行流程和源码分析
- linux中程序执行的流程分析工具——strace
- Android OTA升级原理和流程分析(八)---升级程序update_binary的执行过程
- Java:程序执行流程+命令行获取命令
- [深入理解JVM 一]---Java程序执行流程