一、类的组成
1.变量
-
实例变量(成员变量)
-
类变量(静态变量)
2.方法
-
实例方法
-
类方法(静态方法)
-
构造方法
3.初始化代码块
- 实例初始化块
- 静态初始化块
4.内部类(后面讲)
二、单个类的初始化顺序
1.例子
//Son.java
public class Son
{
int num1 = 10; //实例变量
static int num2 = 20; //类变量
{
System.out.println(num1) ;
System.out.println("实例化代码块") ;
}
static
{
System.out.println(num2) ;
System.out.println("静态代码块") ;
}
//构造方法
public Son()
{
System.out.println("Son") ;
}
}
//Test.java
public class Test
{
public static void main(String[] args)
{
Son son = new Son();
}
}
Test.java中new一个实例son,首先会运行静态变量(static int num2 = 20)和静态代码块;然后运行实例变量和实例代码块;最后运行构造方法。
所以输出结果为:
20 //System.out.println(num2)
静态代码块
10 // System.out.println(num1)
实例化代码块
Son
2.错误例子
static
{
System.out.println(num2) ;
System.out.println("静态代码块") ;
}
static int num2 = 20; //静态变量
如果把将static int num2 = 20 写在静态代码块后面,静态代码块调用静态变量时会报错。
这是因为静态变量与静态代码块是平行关系,谁写在前面就先运行谁,这里将静态变量写在后面,导致先运行静态方法时,找不到静态变量num2,所以报错。
同理,实例变量与实例代码块也是平行关系。
3.结论
单个类的初始化顺序:
(1)静态成员变量,静态代码块(与顺序有关)
(2)实例成员变量,实例代码块(与顺序有关)
(3)构造方法
三、子类与父类的初始化顺序
1.例子
//Parent.java
public class Parent
{
int p_num1 = 20; //实例变量
static int p_num2 = 30; //静态变量
{
System.out.println("Parent的实例化代码块") ;
}
static
{
System.out.println("Parent的静态代码块") ;
}
//构造方法
public Parent()
{
System.out.println("Parent") ;
}
}
//Son.java
public class Son extends Parent
{
int num1 = 10; //实例变量
static int num2 = 20; //类变量
{
System.out.println(num1) ;
System.out.println("实例化代码块") ;
}
static
{
System.out.println(num2) ;
System.out.println("静态代码块") ;
}
//构造方法
public Son()
{
System.out.println("Son") ;
}
}
//Test.java
public class Test
{
public static void main(String[] args)
{
Son son = new Son();
}
}
程序先执行静态部分,父类的静态部分执行完,再执行子类的静态部分;然后执行非静态的方法(包括构造方法)和属性,父类执行完,再执行子类。
输出结果:
Parent的静态代码块
20 //子类Son中的System.out.println(num2)
静态代码块
Parent的实例化代码块
Parent //父类的构造方法
10
实例化代码块
Son
结论:
(1)父类静态变量,父类静态初始化代码块
(2)子类静态变量,子类静态初始化代码块
(3)父类变量,父类初始化块,父类构造方法
(4)子类变量,子类初始化块,子类构造方法