JAVA初始化

在JAVA中變量在使用前,必須初始化,否則在編譯時會報錯。
public void sample()
{
    int i;
    System.out.println(i);// Error -- i not initialized
}

  但是當變量是類的屬性時,情況就有些不一樣了。
public class Sample
{
    int i;
    Object o;
    
    public static void main(String[] args)
    {
        new Sample().print();
    }
    
    public void print()
    {
        System.out.println("int = " + i);// int = 0
        System.out.println("Object = " + o);// Object = null
    }
}

  從運行結果來看,類的屬性總是被自動初始化的。

指定初始化
1、在定義的時候初始化
public class Sample
{
    int i = 1;
    Object o = new String("hello world");
    
    public static void main(String[] args)
    {
        new Sample().print();
    }
    
    public void print()
    {
        System.out.println("int = " + i);// int = 1
        System.out.println("Object = " + o);// Object = hello world
    }
}

2、在構造方法中初始化
public class Sample
{
    int i;
    Object o;
    
    public Sample(int i, Object o)
    {
        this.i = i;
        this.o = o;
    }
    
    public static void main(String[] args)
    {
        new Sample(1, "helloworld").print();
    }
    
    public void print()
    {
        System.out.println("int = " + i);// int = 1
        System.out.println("Object = " + o);// Object = hello world
    }
}

  很明顯,第二種方法更爲靈活,可以在運行時動態指定各個屬性的初始值。
  值得注意的是,無論哪種方法,屬性都會先被自動初始化爲默認值。比如第二種方法,可以通過下面的代碼看出屬性先是被自動初始化爲默認值;對於第一種方法,後面會給說具體的例子說明。
public class Sample
{
    int i;
    Object o;
    
    public Sample(int i, Object o)
    {
        System.out.println("int = " + this.i);// int = 0
        System.out.println("Object = " + this.o);// Object = null
        this.i = i;
        this.o = o;
    }
    
    public static void main(String[] args)
    {
        new Sample(1, "helloworld").print();
    }
    
    public void print()
    {
        System.out.println("int = " + i);// int = 1
        System.out.println("Object = " + o);// Object = hello world
    }
}

初始化的順序
1、在類中屬性初始化的順序是跟定義它們的順序一樣的。雖然在類裏面屬性和方法的定義可能會相互交錯,但是在任何方法被調用之前,所有的屬性都會先被初始化。
public class Sample
{
    Item item1 = new Item(1);
    
    public Sample()
    {
        System.out.println("Constructor sample");
    }
    
    Item item2 = new Item(2);
    
    public void f()
    {
        System.out.println("In f()");
    }
    
    Item item3 = new Item(3);
    
    public static void main(String[] args)
    {
        new Sample().f();
    }
}

class Item
{
    Item(int i)
    {
        System.out.println("Item " + i);
    }
}

  結果如下
Item 1
Item 2
Item 3
Constructor sample
In f()

2、static屬性的初始化
  static屬性總是在需要的時候才被初始化,而且僅被初始化一次,因爲static屬性(或static方法)是屬於類的,是無狀態的。在加載某個類的時候,static屬性會在所有non-static屬性被初始化之前被初始化。
  以下例子可以看出,static的item3對象在item1和item2之前被初始化:
public class Sample
{
    Item item1 = new Item(1);
    
    public Sample()
    {
        System.out.println("Constructor sample");
    }
    
    Item item2 = new Item(2);
    
    public void f()
    {
        System.out.println("In f()");
    }
    
    static Item item3 = new Item(3);
    
    public static void main(String[] args)
    {
        new Sample().f();
    }
}

class Item
{
    Item(int i)
    {
        System.out.println("Item " + i);
    }
}

  結果如下
Item 3
Item 1
Item 2
Constructor sample
In f()

3、類加載過種總結
  • 當第一次顯示通過new創建某個對象、或者直接訪問某個類的static方法(或static屬性)時,JAVA虛擬機會在classpath中找到這個類的class文件;
  • 當class文件被加載後,類中所有的static屬性將被初始化。(注意,static屬性僅會被初始化一次;
  • 當使用new創建該類的一個新對象時,JAVA虛擬機會在堆中分配足夠的空間來存放這個對象;
  • 新分配的空間中,所有的原始類型將被置0(int類型爲0,boolean類型爲false等等),引用類型將被置成null;
  • 接着進行顯示初始化,即屬性在定義時指定的初始化;
  • 最後類的構造方法執行。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章