无父类存在的情况
步骤如下:
虚拟机在首次加载Java类时,会对静态代码块、静态成员变量、静态方法进行一次初始化(静态间按顺序执行)。
只有在调用new方法时才会创建类的实例。
- 类实例创建过程:先初始化类的非静态变量,然后非静态初始块,再构造方法。
例子1:
public class Text {
public static int k = 0;
public static Text t1 = new Text("t1");
public static Text t2 = new Text("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");
{
print("构造块");
}
static {
print("静态块");
}
public Text(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++i;
++n;
}
public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
return ++i;
}
public static void main(String args[]) {
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
分析:
先顺序初始化静态
突然出现(Text t1 = new Text(“t1”);)类实例创建:则按照类实例创建过程:先初始化类的非静态变量,非静态初始块,构造方法 。所以有了1—3;
然后继续顺序加载静态初始化(int i =print(“i”);),则出现7;
继续下去,记住n=99了;
再静态代码块,则出现8,此时,静态已经执行完。
最后到了main方法中的类实例创建(Text t = new Text(“init”);):又类实例创建,根据类实例创建过程,则出现了9–10;
有父类存在的情况
有父才有子,所以当父类存在时(其实Object类是所有类的父类),只是在这两个阶段前(执行静态、执行非静态)前,先运行父类的相关代码
默认该类及其父类JVM未曾加载过
步骤如下:
1.父类静态代码,再子类静态代码(静态都是顺序执行)
2.父类非静态代码,父类构造函数,再子类非静态代码,子类构造函数
例子2:
public class SuperAndSub {
public static void main(String[] args) {
// Super s1 = new Sub();
// Super s2 = new Super();
Sub s3 = new Sub();
}
}
class Super {
static int a = getA();
static {
System.out.println("加载Super的静态块");
}
int b = getB();
{
System.out.println("加载Super的普通块");
}
Super() {
System.out.println("加载Super的构造器");
}
static int getA() {
System.out.println("加载Super的静态变量");
return 1;
}
static int getB() {
System.out.println("加载Super的实例变量");
return 2;
}
}
class Sub extends Super {
static int c = getC();
static {
System.out.println("加载Sub的静态块");
}
int d = getD();
{
System.out.println("加载Sub的普通块");
}
Sub() {
System.out.println("加载Sub的构造器");
}
static int getC() {
System.out.println("加载Sub的静态变量");
return 1;
}
static int getD() {
System.out.println("加载Sub的实例变量");
return 2;
}
}