您的位置:首页 > 编程语言 > Java开发

Java程序执行流程分析

2017-07-03 00:17 267 查看
刚刚在复习JavaSE, 正好复习到 程序执行流程,所以写下这篇博客记录下

问题:一下这段代码的执行顺序

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的内容是最先输出来的。 而且是先父类再子类。 因为没有父类 子类的信息哪儿来? 怎么加载? 其他的就前面的类似了。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: