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;
- 接着進行顯示初始化,即屬性在定義時指定的初始化;
- 最後類的構造方法執行。