Java程序执行顺序

java程序执行顺序(附:阿里面试题解析)

一般情况下程序的入口是main函数,但是一定是先加载main中的代码块吗?

答案:不一定 下面解释一下两种情况.

第一种

main方法在一个具有其他方法或属性的类中;

class Test{
	public static int i=1;
	public static void f(){
		sout("静态方法");
	}
	public void print(){
		sout("普通方法");
	}
	public static void main(String [] args){
		new Test();
	}
}

第二种:

public class Test{
	public static void main(String [] args){
		int i =0;
		sout(i);
	}
}

解析: 静态部分依赖于类,而不是依赖于对象存在.静态部分的加载优先于对象创建,当找到main方法后,JVM会加载main方法所在的类,试图找到类中其他静态的部分.
总结一下执行顺序:

  1. 静态属性,静态方法声明,静态块
  2. 动态属性,普通方法声明,构造块
  3. 构造方法
  4. 如果你不懂他们什么意思请参考Java中静态代码块、构造代码块、构造函数、普通代码块

下面是一道阿里的面试题

public class Text {
   >1 public static int k = 0;
   >2 public static Text t1 = new Text("t1");
   >3public static Text t2 = new Text("t2");
   >4 public static int i = print("i");
   >5 public static int n = 99;
   >6 public int j = print("j");

   >7{
        print("构造块");
    }
   >8 static {
        print("静态块");
    }

   >9 public Text(String str) {
        System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);
        ++i;
        ++n;
    }

   >10 public static int print(String str) {
        System.out.println((++k) + ":" + str + "   i=" + i + "    n=" + n);
        ++n;
        return ++i;
    }

   >11 public static void main(String args[]) {
   >12	sout("start");
   >13	Text t = new Text("init");
    }
}
运行结果:

1:j   i=0    n=0
2:构造块   i=1    n=1
3:t1   i=2    n=2
4:j   i=3    n=3
5:构造块   i=4    n=4
6:t2   i=5    n=5
7:i   i=6    n=6
8:静态块   i=7    n=99
9:j   i=8    n=100
10:构造块   i=9    n=101
11:init   i=10    n=102

该题的注意点: 

类加载过程中,可能调用了实例化过程(因为static可以修饰方法,属性,代码块,内部类),此时则会暂停类加载过程而先执行实例化过程(被打断),执行结束再进行类加载过程,上面阿里那道面试题就是典型的暂停类加载

面试题debug过程
当程序开始时,先找到main入口即 11,这时加载该类里面的非动态属性.1-5顺序执行
当执行完1后,开始2代码,此时出现实例化过程但是被static约束,所以终断类加载,进行实例化过程(加载普通的属性,代码块,构造方法)
执行顺序6-10-6-7-10-9
2代码的实例化过程完成,分配了内存空间,接着执行3代码同样顺序
执行顺序6-10-6-7-10-9
3代码的实例化过程完成,分配了内存空间,开始类加载
4代码执行
执行顺序4-10
5代码执行
8代码执行
10代码执行
这个时候类加载完毕
12代码执行
13代码执行,进行实例化
执行顺序6-10-6-7-10-9-13
程序结束

总结(静态过程为类加载)
1.类中所有属性的默认值(一举而成)

2. 父类静态属性初始化,静态块,静态方法的声明(按出现顺序执行)

3. 子类静态属性初始化,静态块,静态方法的声明 (按出现顺序执行)

4. 调用父类的构造方法,

首先父类的非静态成员初始化,构造块,普通方法的声明(按出现顺序执行)

然后父类构造方法

5. 调用子类的构造方法,

首先子类的非静态成员初始化,构造块,普通方法的声明(按出现顺序执行)

然后子类构造方法

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值