Java类加载及执行顺序(上篇)
这个问题看似简单。其实里面涉及到jvm类加载的机制。关于jvm类加载机制本文章不做介绍。以后专门写一篇文章来介绍类加载机制。
在讲解这个问题前,我们先来看一个例子,看看小伙伴们知道下面的程序的执行的结果吗?
---------------------------------------------------------------------------------------------------
例子1:
public class Person {
//静态变量
private static String type ="类型";
private String name = "Persion";
// 静态变量块
static {
System.out.println("静态方法块开始------------------");
System.out.println("类型-------------------------"+type );
type = "修改类型为人类";
}
// 构造方法
public Person(){
System.out.println();
System.out.println("构造方法开始--------------------");
System.out.println("局部变量name的值----------------"+name);
System.out.println("静态变量type的值--------------------"+type);
}
public static void main(String[] args) {
System.out.println("先new 一个Person对象 P1----------------------");
Person p1 = new Person();
System.out.println("---------------------------------------------");
System.out.println("再new 一个Person对象 P2----------------------");
Person p2 = new Person();
}
}
执行后的结果:

分析:
在分析这个例子前,先看几个概念:
1、静态变量
静态变量也叫类变量,在类中以static关键字声明,但必须在方法、构造方法和语句块之外。无论一个类创建了多少个对象,类只拥有类变量的一份拷贝.
如上面的例子1,Person类的type就是静态变量。在例子中,我们new了两个对象p1,p2。但是他们的type都是共用Person类的type.两个对象的type都指向的类的type。
2、静态代码块
静态代码块是使用static和{}修饰的那一段代码,在类被加载的时候就运行了,而且只运行一次,并且优先于各种代码块以及构造函数。如果一个类中有多个静态代码块,会按照书 写顺序依次执行。在静态代码块里不能包含普通的成员变量。
从执行结果里,我们可以看出。在创建一个p1对象时,先执行了静态变量和静态变量块,然后再执行的构造方法。创建p2对象时,没有再执行静态变量和静态变量块,直接执行的构造方法。
所以,从上面例子,我们知道一个类的执行顺序是:
1、静态变量/静态代码块
2、局部变量初始化
3、构造方法
这里,有一个问题,小伙伴要问了,静态变量和静态代码块谁先执行呢?这里不管是静态变量之间,还是静态代码块之间或者静态变量与静态代码块的执行顺序都依赖于他们的程序里的书写顺序,谁在前面,谁先执行。我们看下面的例子
例子2:
public class Test {
// 静态变量
private static int x = 1;
private static int y = 0;
//静态代码块
static {
x = 2;
y = 1;
}
public static void main(String[] args) {
Test t1 = new Test();
System.out.println("x的值---------------------"+t1.x);
System.out.println("y的值---------------------"+t1.y);
}
}
结果:

例子3:
我们把例子2的静态代码块放到静态变量前,看看会有什么变化
public class Test {
//静态代码块
static {
x = 2;
y = 1;
}
// 静态变量
private static int x = 1;
private static int y = 0;
public static void main(String[] args) {
Test t1 = new Test();
System.out.println("x的值---------------------"+t1.x);
System.out.println("y的值---------------------"+t1.y);
}
}
结果:

所以,通过上面的三个小例子。我们可以得出一个Java类的执行顺序是按照如下的顺序执行:
1、静态变量和静态块赋值(按照声明顺序)
2、为成员变量初始化
3、构造方法
这里只介绍了简单的几个情况。下一篇文章将扩展到有父类的情况。如果要更加深入了解类加载,请看关于类加载到下篇。
浙公网安备 33010602011771号