深啃JAVA - 1、認識類 - 創建和銷燬對象

最近在研讀Effective JAVA這一本書,這本書可以說是開發階段中對平時開發的設計提供了一個比較好的規範思想,避免設計時產生不必要的資源浪費,提高軟件性能的一方面,廢話不多話,讓我們一步步進入開發中常見的做法及優化程序的方案。

一、認識類:考慮用靜態工廠方法代替構造器

在類的使用中,我們避免對一個類進行創建,但是你是否知道,類創建的幾個問題?

1、爲什麼要創建類

2、類什麼時候被加載初始化和銷燬

3、創建類多了有什麼隱患

4、有什麼好的方案代替類的構造器

 

那類什麼時候被加載?

類的加載是通過類加載器(Classloader)完成的,它既可以是餓漢式加載類[eagerly load](也就是只要有其他類引用了它就加載),也可以是懶加載[lazy load](等到類初始化發生的時候才加載)

 

那類什麼時候被加載?

類的加載是通過類加載器(Classloader)完成的,它既可以是餓漢式加載類[eagerly load](也就是只要有其他類引用了它就加載),也可以是懶加載[lazy load](等到類初始化發生的時候才加載)

 

類什麼時候初始化?

加載完類後,類的初始化就會被觸發一致發生,意味着它會初始化所有類靜態成員,以下情況一個類被初始化:

1)、實例通過使用new()關鍵字創建或者使用class.forName()反射,但它有可能導致ClassNotFoundException。

2)、類的靜態方法被調用

3)、類的靜態域被賦值

4)、靜態域被訪問,而且它不是常量

5)、在頂層類中執行assert語句

反射同樣可以使類初始化,比如java.lang.reflect包下面的某些方法,JLS嚴格的說明:一個類不能被任何除以上的原因初始化。


類是如何被初始化?

現在我們知道說明時候觸發類的初始化了,還需瞭解一下類初始化的一些規則:

1)、類從頂至底的順序初始化

2)、基類(父類)早於子類的初始化

3)、如果類的初始化是由於訪問靜態域而觸發,那麼只有聲明靜態域的類才被初始化,而不會觸發超類的初始化或者子類的初始化,即使靜態域被子類或子接口或它的實現類所實現

4)、接口初始化不會導致父接口的初始化

5)、靜態域的初始化是在類的靜態初始化期間,非靜態域的初始化時在類的實例創建期間。這意味着靜態域初始化在非靜態域之前。

6)非靜態域通過構造器初始化,子類在做任何初始化之前構造器會隱含地調用父類的構造器,它保證了非靜態或實例變量(父類)初始化早於子類

初始化例子:

這是一個有關類被初始化的例子,你可以看到哪個類被初始化:

public class ClassInitializationTest {  
    public static void main(String args[]) throws InterruptedException {  
        NotUsed o = null;  
        Child t = new Child();  
        System.out.println((Object)o == (Object)t);  
    }  
}  
   
/** 
 * 父類 
 */  
class Parent {  
    static { System.out.println("static block of Super class is initialized"); }  
    {System.out.println("non static blocks in super class is initialized");}  
}  
   
class NotUsed {  
    static { System.out.println("NotUsed Class is initialized "); }  
}  
   
/** 
 *  子類繼承Parent
 */  
class Child extends Parent {  
    static { System.out.println("static block of Sub class is initialized in Java "); }  
    {System.out.println("non static blocks in sub class is initialized");}  
}  

以上程序的輸出結果就是:

static block of Super class is initialized  

static block of Sub class is initialized in Java  

non static blocks in super class is initialized  

non static blocks in sub class is initialized  

false 

從上面結果可以看出:

1、父類的初始化早於子類

2、靜態變量或者代碼塊初始化早於非靜態塊和域

3、沒使用的類根本不會被初始化,因爲它沒有被使用


         (未完,待續......)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章