1、概念
在进入正题之前,我们首先需要知道的一个概念就是神马才是代码块。那么神马才是代码块呢?下面给出正解。
所谓代码块,在Java中,就是指使用大括号{}括起来的代码部分。
2、代码块的分类
关于代码块的分类,主要有四种:局部代码块、构造代码块、静态代码块和同步代码块。
1)局部代码块
局部代码块是指在方法中给出的一个代码块,其主要作用就是用来限定变量的生命周期,及早释放,提高内存的利用率。
2)构造代码块
构造代码块是指存在于类中方法外且被大括号{}括起来的代码部分,其主要作用是将多个构造方法中相同部分代码提取出来存放到了一起,使得代码更加的简洁。该代码块在每次调用构造方法时都会执行,并且在构造方法前执行。
3)静态代码块
静态代码块是指存在于类中方法外且被大括号{}括起来的代码部分,与构造代码块不同的是,该代码块在大括号{}前加上了一个static修饰符,用以表示该代码块是一个静态代码块。该代码块主要用于给类进行初始化,在类加载的时候执行,并且只执行一次。
4)同步代码块(主要用于多线程中)
3、代码块执行过程
上面已经对不同代码块的分类做了一个简单的介绍,下面接着对代码块的执行过程的分析。
3.1 简单执行过程分析
首先给出测试代码和运行结果。
测试代码:
class Student {
static{
System.out.println("Student静态代码块.");
}
{
System.out.println("Studen构造代码块.");
}
public Student(){
System.out.println("Student构造方法.");
}
}
public class Test {
static{
System.out.println("Test主类静态代码块.");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("我是main方法.");
Student stu = new Student();
Student stu2 = new Student();
}
}
运行结果:
根据执行结果我们可以看到,Student的静态代码块只执行了一次,而构造代码块执行了两次,且每次都优先于构造方法执行。其原因是因为静态代码块只在首次创建实例对象,将字节码加载到方区内存中静态区时调用,之后不再调用。
3.2 继承关系中的执行过程
同样的首先给出测试代码和运行结果。
测试代码:
class Father{
static{
System.out.println("静态代码块Father.");
}
{
System.out.println("构造代码块Father.");
}
public Father(){
System.out.println("构造方法Father.");
}
}
class Son extends Father{
static{
System.out.println("静态代码块Son.");
}
{
System.out.println("构造代码块Son.");
}
public Son(){
System.out.println("构造方法Son.");
}
}
public class Test {
public static void main(String[] args) {
Son son = new Son();
}
}
运行结果:
根据运行结果我们可以看到,当子父类中都有静态代码块、构造代码块、构造方法时,它们的执行流程是:1)父类静态代码块;2)子类静态代码块;3)父类构造代码块;4)父类构造方法;5)子类构造代码块;6)子类构造方法。
具体分析:
当在main方法中执行” Son son = new Son(); “语句时,就会去加载Son进入内存,因为Son继承于Father类,所以Father将优先于Son被加载。在将Father、Son两个类的字节码加载进方法区内存中时其对应的静态代码块也将会依次得到执行,这就是为什么一开始输出”静态代码块Father.”、”静态代码块Son.“的原因。紧接着执行Son的空参构造方法进行初始化,又由于构造方法内部默认存在super()方法对其父类Father进行空参构造方法的调用,所以接着输出的是”构造代码块Father.“、”构造方法Father.“,其次才是”构造代码块Son.“、”构造方法Son.“。
以上就是对Java中代码块执行过程的一个简单分析,有啥疏漏欢迎补充。