Java代碼塊
阿新 • • 發佈:2018-05-20
com 示例代碼 實例 類的初始化 接收 -c 使用 pub IT
- 類的三大成員:成員變量、構造方法、方法,初始化代碼塊是類的第4個成員
- 初始化塊用於對類或者對象的初始化,
- 一個類的初始化塊可以有0~多個,按先後順序執行
- 跟實例方法-->類方法、實例變量-->類變量一樣,也可以用static修飾初始化塊,靜態初始化塊-->非靜態初始化塊
- 初始化塊總是先於構造器執行
- 非靜態初始化塊
- 非靜態初始化塊相當於是對構造器的補充,用於創建對象時給對象的初始化,在構造器之前執行
- 如果一段初始化代碼對所有構造器完全相同,且無需接收參數,那就可以將其提取到非靜態初始化代碼塊中
- 在繼承中,先後執行父類A的非靜態塊、構造器,再執行父類B的非靜態塊、構造器,最後才執行子類的非靜態塊、構造器
- 實際上,經過編譯後,非靜態塊已經添加到構造器中,且位於所有構造器代碼的前面
- 靜態初始化塊下面通過一段代碼,看看繼承中的靜態塊、非靜態塊、構造方法的執行順序
- 靜態初始化塊用static修飾,又叫類初始化塊
- 非靜態塊負責對對象執行初始化,而類初始化塊負責對類進行初始化,因此類初始化塊是在類初始化階段就執行
- 靜態塊跟靜態方法一樣,不能訪問非靜態成員
- 在繼承中,先後執行父類A的靜態塊,父類B的靜態塊,最後子類的靜態塊,然後再執行父類A的非靜態塊和構造器,然後是B類,最後執行子類的非靜態塊和構造器
- 因為靜態塊是在類的初始化階段完成的,因此在創建某個類的第二個對象時,該類的靜態塊就不會執行了
public class Test{
public static void main(String[] args) {
C c1=new C();
System.out.println("--------下面第二次創建C類對象---------");
C c2=new C();
}
}
class C extends B{
static {
System.out.println("C的靜態代碼塊");
}
{
System.out.println("C的非靜態代碼塊");
}
C(){
System.out.println("C的無參構造方法");
}
C(String str){
System.out.println("C的有參構造方法");
}
}
class B extends A{
static {
System.out.println("B的靜態代碼塊");
}
{
System.out.println("B的非靜態代碼塊");
}
B(){
System.out.println("B的無參構造方法");
}
B(String str){
System.out.println("B的有參構造方法");
}
}
class A{
static {
System.out.println("A的靜態代碼塊");
}
{
System.out.println("A的非靜態代碼塊");
}
A(){
System.out.println("A的無參構造方法");
}
A(String str){
System.out.println("A的有參構造方法");
}
}
輸出為:
A的靜態代碼塊
B的靜態代碼塊
C的靜態代碼塊
A的非靜態代碼塊
A的無參構造方法
B的非靜態代碼塊
B的無參構造方法
C的非靜態代碼塊
C的無參構造方法
--------下面第二次創建C類對象---------
A的非靜態代碼塊
A的無參構造方法
B的非靜態代碼塊
B的無參構造方法
C的非靜態代碼塊
C的無參構造方法
靜態初始化塊與靜態成員變量的執行順序
- JVM第一次使用某個類時,在準備階段給所有靜態成員分配內存,在初始化階段初始化這些靜態成員變量,就是執行初始化代碼或者聲明成員變量時指定的初始值,執行順序與源代碼中的順序相同
- 按源代碼中的先後順序執行,見示例代碼:
public class Test{
public static void main(String[] args) {
A a=new A();
System.out.println(a.num); //輸出10,而不是6,說明先執行聲明賦值6,然後才執行靜態塊賦值10
}
}
class A{
public static int num=6;
static{
num=10;
}
}
Java代碼塊