一。JAVA中執(zhí)行順序
- 靜態(tài)塊
- 塊
- 構(gòu)造器
- 父類(lèi)構(gòu)造器
二。JAVA中賦值順序
- 靜態(tài)塊直接賦值
- 塊直接賦值
- 父類(lèi)繼承的屬性已賦值
- 靜態(tài)變量聲明時(shí)賦值
- 成員變量聲明時(shí)賦值
- 構(gòu)造器賦值
第一部分很好測(cè)試,我們只需要寫(xiě)一個(gè)子類(lèi),類(lèi)中定義一個(gè)靜態(tài)塊,一個(gè)普通塊,一個(gè)構(gòu)造器,它的父類(lèi)構(gòu)造器,都打印一條語(yǔ)句,即可明白它們直接的執(zhí)行順序
Mastiff類(lèi)
- <span style="font-size: medium;">
-
-
- public class Mastiff extends Dog {
- public Mastiff() {
- System.out.println("Mastiff");
- }
-
- {
- System.out.println("block");
- }
- static {
- System.out.println("static block");
- }
-
- public static void main(String[] args){
- Mastiff mastiff=new Mastiff();
-
- }
- }
- </span>
DOG類(lèi)
- <span style="font-size: medium;">
-
-
- public class Dog {
- public Dog() {
- System.out.println("Dog");
- }
- }
- </span>
運(yùn)行結(jié)果為:
static block Dog block Mastiff
|
也就是說(shuō),在我們的程序中,實(shí)例化一個(gè)類(lèi)對(duì)象的時(shí)候,運(yùn)行順序?yàn)椋?/span>
- 靜態(tài)塊
- 父類(lèi)構(gòu)造器
- 本類(lèi)中的塊
- 本類(lèi)的構(gòu)造器
我們可以更進(jìn)一步,如果在父類(lèi)中也有塊和靜態(tài)塊呢?
DOG類(lèi)改進(jìn)后源碼
- <span style="font-size: medium;">
-
-
- public class Dog {
- public Dog() {
- System.out.println("Dog");
- }
- static{
- System.out.println("super static block");
- }
-
- {
- System.out.println("super block");
- }
- }
- </span>
Mastiff改進(jìn)后源碼
- <span style="font-size: medium;">
-
-
- public class Mastiff extends Dog {
- public Mastiff() {
- System.out.println("Mastiff");
- }
-
- {
- System.out.println("block");
-
- }
- static {
- System.out.println("static block");
- }
-
- public static void main(String[] args){
- Mastiff mastiff=new Mastiff();
- }
- }
- </span>
運(yùn)行的結(jié)果為:
super static block static block super block Dog block Mastiff
|
也就是說(shuō)此時(shí)的運(yùn)行順序?yàn)椋?/span>
- 父類(lèi)靜態(tài)塊
- 自身靜態(tài)塊
- 父類(lèi)塊
- 父類(lèi)構(gòu)造器
- 自身塊
- 自身構(gòu)造器
好了,知道了運(yùn)行的順序,那么這是為什么呢?
這就要從JVM中類(lèi)的裝載機(jī)制和實(shí)例化機(jī)制開(kāi)始說(shuō)起,這里因?yàn)橹黝}原因,先不討論,有興趣的同學(xué)可以自己查資料。
|
我們?cè)賮?lái)討論第二個(gè)問(wèn)題,一個(gè)變量的值,它有可能在哪些地方確定呢??
- 從父類(lèi)繼承該值(包括:1.作為父類(lèi)的成員變量已經(jīng)賦值 2.在父類(lèi)的塊中賦值 3.在父類(lèi)的構(gòu)造器中賦值)
- 在構(gòu)造器中對(duì)其進(jìn)行賦值
- 在塊中進(jìn)行賦值
-
在方法調(diào)用中進(jìn)行賦值
現(xiàn)在假設(shè)在我們剛剛的例子中,有一個(gè)變量type,表示狗的品種
- <span style="font-size: medium;">
-
-
- public class Dog {
- public String type="父類(lèi)成員變量賦的值";
- public Dog() {
- System.out.println("父類(lèi)構(gòu)造器--type-->"+type);
- type="父類(lèi)構(gòu)造器賦的值";
- System.out.println("父類(lèi)構(gòu)造器----type--->"+type);
- }
-
- {
- System.out.println("block---type--->"+type);
- type="父類(lèi)塊賦的值";
- }
- }
- </span>
- <span style="font-size: medium;">
-
-
- public class Mastiff extends Dog {
- public String type="成員變量賦的值";
- public Mastiff() {
- System.out.println("構(gòu)造器---type--->"+type);
- type="構(gòu)造器賦的值";
- }
-
- public void say(){
- System.out.println("say---type---->"+type);
- }
-
- {
- System.out.println("block---type--->"+type);
- type="塊賦的值";
-
- }
-
- public static void main(String[] args){
- Mastiff mastiff=new Mastiff();
- mastiff.say()</span><span style="font-size: medium;">;</span><span style="font-size: medium;">
- }
- }
- </span>
執(zhí)行結(jié)果如下:
block---type--->父類(lèi)成員變量賦的值 父類(lèi)構(gòu)造器--type-->父類(lèi)塊賦的值 父類(lèi)構(gòu)造器----type--->父類(lèi)構(gòu)造器賦的值 block---type--->成員變量賦的值 構(gòu)造器---type--->塊賦的值 say---type---->構(gòu)造器賦的值
|
答案很明顯,賦值順序?yàn)椋?/span>
- 父類(lèi)成員變量賦值
- 父類(lèi)塊賦值
- 父類(lèi)構(gòu)造器賦值
- 自身成員變量賦值
- 自身塊賦值
- 自身構(gòu)造器賦值
結(jié)合我們前面說(shuō)的程序中的執(zhí)行順序,這個(gè)顯然是很好理解的:
1.成員變量賦值>>>塊賦值>>>構(gòu)造器賦值
2.父類(lèi)的塊>>父類(lèi)構(gòu)造器>>自身塊>>自身構(gòu)造器
又因?yàn)橐粋€(gè)成員變量是不可能在靜態(tài)變量中賦值的,而且又前面程序執(zhí)行順序可知
靜態(tài)塊>>塊
所以,程序的賦值步驟為
- 父類(lèi)的靜態(tài)變量賦值
- 自身的靜態(tài)變量賦值
- 父類(lèi)成員變量賦值
- 父類(lèi)塊賦值
- 父類(lèi)構(gòu)造器賦值
- 自身成員變量賦值
- 自身塊賦值
- 自身構(gòu)造器賦值
|