1. 程式人生 > >動手動腦-3

動手動腦-3

package 動手動腦;

public class 試驗 {
public static void main(String[] args) {
    Foo  obj1=new Foo();
    Foo  obj2=new Foo();
    System.out.println(obj1==obj2);
}
}
class  Foo{
    int value=100;
}

這個程式的執行結果是false,建立類Foo的物件obj1,然後立刻又建了類Foo的物件obj2,這兩個物件是不同的,就像是克隆了一個新的物件,所以最終結果為false.

構造方法的特殊之處:1、沒有返回值

                                   2、與類名相同

                                   3、對物件進行初始化

                                   4、在建類時自動建立一個預設建構函式,但是如果自己建立了有參建構函式,將不再自動建立預設建構函式。

package 動手動腦;

public class InitializeBlockClass {
    {
        field=200;
    }
    public int field=100;
    public InitializeBlockClass(int value) {
        this.field=value;
    }
    public InitializeBlockClass() {
        
    }
    public static void main(String[]args) {
        InitializeBlockClass obj
=new InitializeBlockClass(); System.out.println(obj.field); obj=new InitializeBlockClass(300); System.out.println(obj.field); } }

這個程式的執行結果是:100

                                       300

第一次建立物件呼叫的是無參建構函式,然後就要呼叫上面的field的值,這是採用就近原則,所以第一次輸出field的值為100,第二次建立物件,呼叫的是有參建構函式,這是建構函式自己賦值為300,所以第二次輸出為300.

 Java欄位初始化的規律:

靜態初始化生成例項變成你賦給他的值,先執行靜態初始化,如果沒有例項化,按照初始化和構造方法在程式中出現的順序執行。

當多個類之間有繼承關係時,建立子類物件會導致父類初始化塊的執行。

class Root
{
    static{
        System.out.println("Root的靜態初始化塊");
    }
    {
        System.out.println("Root的普通初始化塊");
    }
    public Root()
    {
        System.out.println("Root的無引數的構造器");
    }
}
class Mid extends Root
{
    static{
        System.out.println("Mid的靜態初始化塊");
    }
    {
        System.out.println("Mid的普通初始化塊");
    }
    public Mid()
    {
        System.out.println("Mid的無引數的構造器");
    }
    public Mid(String msg)
    {
        //通過this呼叫同一類中過載的構造器
        this();
        System.out.println("Mid的帶引數構造器,其引數值:" + msg);
    }
}
class Leaf extends Mid
{
    static{
        System.out.println("Leaf的靜態初始化塊");
    }
    {
        System.out.println("Leaf的普通初始化塊");
    }    
    public Leaf()
    {
        //通過super呼叫父類中有一個字串引數的構造器
        super("Java初始化順序演示");
        System.out.println("執行Leaf的構造器");
    }

}

public class TestStaticInitializeBlock
{
    public static void main(String[] args) 
    {
        new Leaf();
        

    }
}

執行結果為:

Root的靜態初始化塊
Mid的靜態初始化塊
Leaf的靜態初始化塊
Root的普通初始化塊
Root的無引數的構造器
Mid的普通初始化塊
Mid的無引數的構造器
Mid的帶引數構造器,其引數值:Java初始化順序演示
Leaf的普通初始化塊
執行Leaf的構造器

 通過執行結果我發現:在呼叫這個方法時,有super,呼叫父類,然後先呼叫第一個父類中的靜態初始化塊,然後呼叫子類的靜態初始化塊,然後呼叫子類的子類中的靜態初始化塊,接著呼叫父類中的普通初始化塊和無參的構造塊,然後子類中的普通、無參構造、有參構造初始化塊,最後呼叫方法中System.out.println()中要輸出的內容 靜態初始化塊的執行順序為:
  1. 靜態初始化塊的優先順序最高,也就是最先執行,並且僅在類第一次被載入時執行;
  2. 非靜態初始化塊和建構函式後執行,並且在每次生成物件時執行一次;
  3. 非靜態初始化塊的程式碼會在類建構函式之前執行。因此若要使用,應當養成把初始化塊寫在建構函式之前的習慣,便於除錯;
  4. 靜態初始化塊既可以用於初始化靜態成員變數,也可以執行初始化程式碼;
  5. 非靜態初始化塊可以針對多個過載建構函式進行程式碼複用。
    package 動手動腦;
    
    public class 靜態方法 {
    public static int a=10;
    public void  setvalue() {
        System.out.println(a);
    }
    public static void main(String[]args) {
        System.out.println(a);
        靜態方法 j=new 靜態方法();
        j.setvalue();
    }
    }

    程式的執行結果為:10  10  說明靜態方法可以呼叫靜態變數,非靜態方法也可以呼叫靜態變數。