靜態代碼塊是如何執行的?一般用在什麼地方?

Jvm的類加載機制中,我們說過有一個階段是初始化(Initialization),這個階段的應用類加載器(Application or App ClasLoader)會收集所有的靜態代碼塊並執行,而且只執行一次。所以這裏有一個誤區,很多人認爲Java靜態代碼塊是在類被加載時自動執行,這是錯誤的,需要注意的是,靜態代碼塊只在類加載的初始化階段執行。
類被加載了,不一定會執行靜態代碼塊,詳情看代碼:

public class ClassLoaderTest {
	public static void main(String[] args) {
		System.out.println("main()函數===" + LoaderTest.class);
	}
}

class LoaderTest {
	static {
		System.out.println(">>>靜態代碼塊執行了沒有<<<");
	}
}

那麼,靜態代碼塊是如何執行的呢?
靜態代碼塊會在類加載的初始化階段執行,而且只執行一次。

如果繼承父類,則會先執行父類中的靜態代碼塊,然後再執行子類中的靜態代碼塊;

實例對象時,會先執行父類中的非靜態代碼塊,父類中的構造方法,然後再執行子類中的非靜態代碼塊,子類中的構造方法!

public class Father {
	static {
		System.out.println(">>>Father靜態代碼塊<<<");
	}

	{
		System.out.println(">>>Father非靜態代碼塊<<<");
	}

	public Father() {
		System.out.println(">>>Father無參構造<<<");
	}
}
public class TestSon extends Father {

	static {
		System.out.println(">>>TestSon靜態代碼塊<<<");
	}

	{
		System.out.println(">>>TestSon非靜態代碼塊<<<");
	}

	public TestSon() {
		System.out.println(">>>TestSon無參構造<<<");
	}
	
	public static void main(String[] args) {
		System.out.println("TestSon的main()函數");
		TestSon son1 = new TestSon();
		System.out.println("--------------------");
		TestSon son2 = new TestSon();
	}
}

靜態代碼塊一般用在什麼地方?
1)在項目啓動時,加載某個類,對數據進行數據化(如初始化基礎數據或數據庫連接池)。 

// 輸出服務器編碼
static {
		Charset defaultCharset = Charset.defaultCharset();
		String name = defaultCharset.name();
		System.out.println("\n"+"\t"+"當前服務器採用的字符集是:" + name);
	}

2)工具類中使用static靜態代碼塊進行初始化,當第一次訪問工具類時,就會先進行初始化(只會執行一次),保存到靜態全局屬性中,當其他類再次訪問時,將直接使用初始化數據(如獲取一個單例sessionFactory)。

public class HibernateUtil {

    private static final SessionFactory sessionFactory;
    private static final ThreadLocal session = new ThreadLocal();

    static {
        try {
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
}

 

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