重溫java基礎,以免自己以後犯原則性錯誤,這是最基本,最基礎的東西。
直接上代碼:
A.java
public class A {
int a1 = 8;
int a2 = getA2();
{
int a3 = 9;
System.out.println("top of A() a1=" + a1 + " a2=" + a2 + " a3=" + a3);
}
public A() {
this(66);
System.out.print("A 構造函數\n");
}
{
System.out.println("below A()..has start");
}
public A(int num) {
System.out.print("A 帶參數構造函數: " + num + "\n");
}
static {
System.out.println("I`m a static {} from class A..");
}
int getA2() {
System.out.println("getA2..");
return 7;
}
public void methodA() {
System.out.println("methodA");
}
}
B.java
public class B extends A {
int b1 = 0;
int b2 = getB2();
{
int b3 = 5;
System.out.println("top of B() b1=" + b1 + " b2=" + b2 + " b3=" + b3);
}
public B() {
this(33);
// super(44);//添加super語句,會導致實例化時直接執行父類帶參數的構造函數
System.out.print("B 構造函數\n");
}
public B(int num) {
// 添加super語句,會導致實例化時直接執行父類帶參數的構造函數
// 前提是帶參數的構造函數B會被運行(new實例化或this)
// super(77);
System.out.print("B 帶參數構造函數:" + num + "\n");
}
{
System.out.println("below B()..has start");
}
static {
System.out.println("I`m a static {} from class B..");
}
int getB2() {
System.out.println("getB2..");
return 33;
}
@Override
public void methodA() {
System.out.println("methoaA int class B");
super.methodA();
}
}
main.java
public class mymain {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("main app run..");
B b = new B();
// B b = new B(22);
b.methodA();
}
}
實驗一
思考一下打印輸出的順序?
打印輸出結果:
main app run..
I`m a static {} from class A..
I`m a static {} from class B..
getA2..
top of A() a1=8 a2=7 a3=9
below A()..has start
A 帶參數構造函數: 66
A 構造函數
getB2..
top of B() b1=0 b2=33 b3=5
below B()..has start
B 帶參數構造函數:33
B 構造函數
methoaA int class B
methodA
分析:B類無參的構造函數中的this語句並沒有影響到父類A類的構造函數執行順序
***********************************分割線***********************************
實驗二
如果我把B類無參數的構造函數,this(33)換成super(44)呢,看一下結果?
main app run..
I`m a static {} from class A..
I`m a static {} from class B..
getA2..
top of A() a1=8 a2=7 a3=9
below A()..has start
A 帶參數構造函數: 44
getB2..
top of B() b1=0 b2=33 b3=5
below B()..has start
B 構造函數
methoaA int class B
methodA
***********************************分割線***********************************
實驗三
main app run..
I`m a static {} from class A..
I`m a static {} from class B..
getA2..
top of A() a1=8 a2=7 a3=9
below A()..has start
A 帶參數構造函數: 77
getB2..
top of B() b1=0 b2=33 b3=5
below B()..has start
B 帶參數構造函數:33
B 構造函數
methoaA int class B
methodA
綜合結論:
一個類的實例化過程:
1,首先會執行類中static代碼塊(不管代碼塊是否在類的開頭還是末尾處),如果這個類有父類,同樣會優先查找父類中的static代碼塊,然後是當前類的static。
2,然後會從父類的第一行開始執行,直至代碼末尾處,中間不管是有賦值還是method調用,都會按順序一一執行(method),普通代碼塊{ }...
3,其次纔是父類的構造函數,執行帶參數或不帶參數的構造函數,依賴於實例化的類的構造函數有沒有super父類的帶參或不帶參的構造函數,上邊試驗二三已經證明。
4,然後會從子類(當前類)的第一行開始執行,直至代碼末尾處,中間不管是有賦值還是method調用,都會按順序一一執行(method),普通代碼塊{ }...
5,其次會是子類(當前類)的構造函數,按順序執行。
6,最後是類方法的調用執行,如果子類覆蓋了父類的method,執行時會先執行子類覆蓋的method,method內如果有super.method(),纔會調用父類的同名method,否則不會。