阿里面試題——Java對象初始化

Java對象初始化

這是一道阿里巴巴的關於Java對象初始化的面試題,堪稱經典,代碼很簡單(編寫格式作了些修改),可是須要面試者對Java中對象初始化有一個透徹的認識,那麼經過這道面試題,對我有點啓發,因此但願在這裏分享給你們,但願能給迷惘的初學者一塊兒指引,下面咱們直入主題,先看看代碼:面試

public class InitializeDemo {
	private static int k = 1;
	private static InitializeDemo t1 = new InitializeDemo("t1");
	private static InitializeDemo t2 = new InitializeDemo("t2");
	private static int i = print("i");
	private static int n = 99;
	static {
		print("靜態塊");
	}
	private int j = print("j");
	{
		print("構造塊");
	}
	public InitializeDemo(String str) {
		System.out.println((k++) + ":" + str + " i=" + i + " n=" + n);
		++i;
		++n;
	}
	public static int print(String str) {
		System.out.println((k++) + ":" + str + " i=" + i + " n=" + n);
		++n;
		return ++i;
	}
	public static void main(String args[]) {
		new InitializeDemo("init");
	}
}
複製代碼

作些小補充,這也是不少Java學習者最初都能接觸到的一些可是不是很理解的概念:sql

核心理念bash

  1. 靜態屬性和靜態代碼塊都是在類加載的時候初始化和執行,二者的優先級別是一致的,且高於非靜態成員,執行按照編碼順序。
  2. 非靜態屬性和匿名構造器在全部的構造方法以前執行,二者的優先級別一致,執行按照編碼順序。
  3. 以上執行完畢後執行構造方法中的代碼。

讀者仔細揣摩上面三條句子,也就是Java對象初始化的順序,也就明白以上程序的輸出結果爲何以下:架構

j   i=0    n=0
構造塊   i=1    n=1
t1   i=2    n=2
j   i=3    n=3
構造塊   i=4    n=4
t2   i=5    n=5
i   i=6    n=6
靜態塊   i=7    n=99
j   i=8    n=100
構造塊   i=9    n=101
init   i=10    n=102
複製代碼

若是仍是沒有明白,就看下面詳解,一下詳解的順序就是按照上文的核心理念的順序來執行的(建議讀者把本身帶入JVN的世界裏,跟着JVM一步一步往下面走):併發

  1. 運行main方法的時候,JVM會調用ClassLoader來加載InitializeDemo類,那麼一塊兒源於此次加載。
  2. 上面有四個靜態屬性,因此會按順序逐一初始化這四個靜態屬性。
  3. private static int k = 1; 此時將k初始化爲1。
  4. private static InitializeDemo t1 = new InitializeDemo("t1");建立InitializeDemo對象,那麼按照核心理念中的順序,先執行private int j = print("j");,打印出j,而後執行構造 塊,最後執行構造方法。 5.private static InitializeDemo t2 = new InitializeDemo("t2");同步驟4。 6.private static int i = print("i");打印i。 7.private static int n = 99;直到這一步,n才被賦值爲99,以前是從默認的0開始++的。 8.靜態屬性初始化完畢,代碼走到靜態塊,打印出靜態塊,此時n=99。 9.靜態屬性和靜態塊執行完畢,而後執行main方法中的代碼new InitializeDemo("init"); 10.main方法中建立對象,先初始化非靜態屬性,private int j = print("j");打印j,而後執行構造塊,最後執行構造方法。

不知道我解說清楚了沒有,只要把握住核心理念,碰到在複雜的問題也都不會怕了。分佈式

用一個公式歸納一下Java對象初始化執行優先級別高併發

(靜態屬性=靜態代碼塊)> (非靜態屬性 = 構造塊)> 構造方法性能

總結一下核心理念學習

  1. 靜態只在類加載的時候執行,且執行一次。
  2. 非靜態只在實例化的時候執行,且每次實例化都執行。
  3. 靜態在非靜態以前執行。
  4. 靜態屬性和靜態塊的執行順序取決於編碼順序,對它們一視同仁。
  5. 非靜態屬性和構造塊的執行順取決於編碼順序,對它們也一視同仁。
  6. 最後執行構造方法。

上面的總結有點繞對吧,問題進一步簡化的話,就更好理解了: 讀者將靜態代碼塊視爲一個靜態屬性,將構造塊視爲一個非靜態屬性,那麼問題簡化到了這種路線「靜態屬性-->非靜態屬性-->構造方法「ui

不積跬步無以致千里,祝願你們學習進步,樂於分享~ ~

寫在最後

最後,歡迎作Java的工程師朋友們加入Java高級架構進階Qqun:963944895

羣內有技術大咖指點難題,還提供免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)

比你優秀的對手在學習,你的仇人在磨刀,你的閨蜜在減肥,隔壁老王在練腰, 咱們必須不斷學習,不然咱們將被學習者超越!

趁年輕,使勁拼,給將來的本身一個交代!

相關文章
相關標籤/搜索