天天看點

java 初始化一個對象_java中一個對象的初始化

![](https://box.kancloud.cn/ae5da0f52f45a8b47c8f5376a8d92a02_592x469.png)

http://www.cnblogs.com/miniwiki/archive/2011/03/25/1995615.html

```

public class InitialOrderTest {

// 靜态變量

public static String staticField = "靜态變量";

// 變量

public String field = "變量";

// 靜态初始化塊

static {

System.out.println(staticField);

System.out.println("靜态初始化塊");

}

// 初始化塊

{

System.out.println(field);

System.out.println("初始化塊");

}

// 構造器

public InitialOrderTest() {

System.out.println("構造器");

}

public static void main(String[] args) {

new InitialOrderTest();

}

}

運作以上代碼,我們會得到如下的輸出結果:

1. 靜态變量

2. 靜态初始化塊

3. 變量

4. 初始化塊

5. 構造器

```

```

class Parent {

// 靜态變量

public static String p_StaticField = "父類--靜态變量";

// 變量

public String p_Field = "父類--變量";

protected int i = 9;

protected int j = 0;

// 靜态初始化塊

static {

System.out.println(p_StaticField);

System.out.println("父類--靜态初始化塊");

}

// 初始化塊

{

System.out.println(p_Field);

System.out.println("父類--初始化塊");

}

// 構造器

public Parent() {

System.out.println("父類--構造器");

System.out.println("i=" + i + ", j=" + j);

j = 20;

}

}

public class SubClass extends Parent {

// 靜态變量

public static String s_StaticField = "子類--靜态變量";

// 變量

public String s_Field = "子類--變量";

// 靜态初始化塊

static {

System.out.println(s_StaticField);

System.out.println("子類--靜态初始化塊");

}

// 初始化塊

{

System.out.println(s_Field);

System.out.println("子類--初始化塊");

}

// 構造器

public SubClass() {

System.out.println("子類--構造器");

System.out.println("i=" + i + ",j=" + j);

}

// 程式入口

public static void main(String[] args) {

System.out.println("子類main方法");

new SubClass();

}

}

運作一下上面的代碼,結果馬上呈現在我們的眼前:

父類--靜态變量

父類--靜态初始化塊

子類--靜态變量

子類--靜态初始化塊

子類main方法

父類--變量

父類--初始化塊

父類--構造器

i=9, j=0

子類--變量

子類--初始化塊

子類--構造器

i=9,j=20

```

現在,結果已經不言自明了。子類的靜态變量和靜态初始化塊的初始化是在父類的變量、初始化塊和構造器初始化之前就完成了。

靜态變量、靜态初始化塊,變量、初始化塊初始化了順序取決于它們在類中出現的先後順序。

執行過程分析

(1)通路SubClass.main(),(這是一個static方法),于是裝載器就會為你尋找已經編譯的SubClass類的代碼(也就是SubClass.class檔案)。在裝載的過程中,裝載器注意到它有一個基類(也就是extends所要表示的意思),于是它再裝載基類。不管你創不建立基類對象,這個過程總會發生。如果基類還有基類,那麼第二個基類也會被裝載,依此類推。

(2)執行根基類的static初始化,然後是下一個派生類的static初始化,依此類推。這個順序非常重要,因為派生類的“static初始化”有可能要依賴基類成員的正确初始化。

(3)當所有必要的類都已經裝載結束,開始執行main()方法體,并用new SubClass()建立對象。

(4)類SubClass存在父類,則調用父類的構造函數,你可以使用super來指定調用哪個構造函數(也就是Beetle()構造函數所做的第一件事)。

基類的構造過程以及構造順序,同派生類的相同。首先基類中各個變量按照字面順序進行初始化,然後執行基類的構造函數的其餘部分。

(5)對子類成員資料按照它們聲明的順序初始化,執行子類構造函數的其餘部分。

from:

http://blog.sina.com.cn/s/blog_4cc16fc50100bjjp.html

```

class A{

public static A a = new A();

static {

System.out.println("static");

}

A(){

System.out.println("A");

}

{

System.out.println("no-static");

}

}

public class Test2 {

public static void main(String[] args){

A a =new A();

}

}

```

一個進階的問題:

http://www.ibm.com/developerworks/cn/java/j-lo-clobj-init/

```

public class Test2 {

//單态執行個體 一切問題皆由此行引起

private static final Test2 SINGLE_ENUM_RESOLVER = new

Test2();

private static Map CODE_MAP_CACHE;

static {

CODE_MAP_CACHE = new HashMap();

//為了說明問題,我在這裡初始化一條資料

CODE_MAP_CACHE.put("0","北京市");

}

//private, for single instance

private Test2() {

//初始化加載資料 引起問題,該方法也要負點責任

initEnums();

}

public static void initEnums() {

// ~~~~~~~~~問題從這裡開始暴露 ~~~~~~~~~~~//

if (null == CODE_MAP_CACHE) {

System.out.println("CODE_MAP_CACHE為空,問題在這裡開始暴露.");

CODE_MAP_CACHE = new HashMap();

}

CODE_MAP_CACHE.put("1", "北京市");

CODE_MAP_CACHE.put("2", "雲南省");

//..... other code...

}

public Map getCache() {

return Collections.unmodifiableMap(CODE_MAP_CACHE);

}

public static Test2 getInstance() {

return SINGLE_ENUM_RESOLVER;

}

public static void main(String[] args) {

System.out.println(Test2.getInstance().getCache());

}

}

輸出為:

CODE_MAP_CACHE為空,問題在這裡開始暴露.

{0=北京市}

```