1. 程式人生 > >Java開發筆記(五十二)對象的類型檢查

Java開發筆記(五十二)對象的類型檢查

可靠 all 取值 得到 tar int 獲取 介紹 instance

前面介紹了類的多態性,來自於雞類的實例chicken,既能用來表達公雞實例,也能用來表達母雞實例。可是這導致了一個問題,假如在call方法內部需要手工判斷輸入參數屬於公雞實例還是母雞實例,那該如何是好?所謂“雄兔腳撲朔,雌兔眼迷離,雙兔傍地走,安能辨我是雄雌”,固然編譯器在運行之時能夠自動判斷這是哪種雞,可是若讓程序員自己辨別倒的確是件傷腦筋的事情。雖說傷腦筋,卻也並非無法實現,粗略算來大致有三個辦法能派上用場,接下來分別進行闡述。
第一個辦法,區別公雞和母雞,關鍵在於識別雞的性別。註意到Chicken雞類剛好有個性別類型字段sex,在公雞類中sex固定為0,在母雞類中sex固定為1。於是通過檢查chicken實例的sex屬性取值,即可判斷該實例屬於公雞類還是屬於母雞類。據此可編寫實例類型的鑒別方法,具體代碼如下:

	// 通過屬性字段type檢查某實例的歸屬類
	private static void checkType(Chicken chicken) {
		if (chicken.sex == 0) { // 判斷性別是否為雄性
			System.out.println("檢查類型字段:這是只公雞。");
		} else if (chicken.sex == 1) { // 判斷性別是否為雌性
			System.out.println("檢查類型字段:這是只母雞。");
		} else {
			System.out.println("檢查類型字段:這既不是公雞也不是母雞。");
		}
	}

通過性別類型鑒定歸屬類,這種做法雖然在理論上可行,但事實上並不可靠。因為要是公雞實例的sex取值被意外篡改為1,那該公雞實例豈不是被誤判為母雞了?好比一只公雞做了變性手術,難道它就變成母雞了嗎?篡改只能改變局部特征,並不能改變該事物的內在本質,或者說,血液中流淌著的基因是無法改變的。只要DNA裏面攜帶Y染色體,那麽這只雞從根本上說就是公雞,而不管它外表上如何整形。
由此可見,依據基因檢測,才是檢查實例類型的可靠辦法。在Java代碼中,獲取某實例基因的手段是調用該實例的getClass方法,一旦獲得某只雞的基因,再跟公雞的基因和母雞的基因去比較,分分鐘就比較出結果了。對於公雞類Cock來說,它的基因可通過Cock.class提取;對於母雞類Hen來說,它的基因可通過Hen.class來提取。於是實例類型的鑒別過程便分解為兩個步驟:先調用實例的getClass方法得到它的基因,再將該基因與目標基因進行匹配操作,倘若匹配成功則表示二者是同一種類型。下面是按照基因匹配來檢查實例歸屬類的代碼例子:

	// 通過類的基因檢查某實例的歸屬類
	private static void checkClass(Chicken chicken) {
		if (chicken.getClass().equals(Cock.class)) { // 判斷這只雞的DNA是不是公雞DNA
			System.out.println("檢查對象的類名:這是只公雞。");
		} else if (chicken.getClass().equals(Hen.class)) { // 判斷這只雞的DNA是不是母雞DNA
			System.out.println("檢查對象的類名:這是只母雞。");
		} else {
			System.out.println("檢查對象的類名:這既不是公雞也不是母雞。");
		}
	}

上述的基因檢測手段很好很強大,然而其缺點也很明顯,就是太專業太啰嗦了。本來僅僅是個判斷實例類型的小事,何必要搞得興師動眾、追根溯源呢?因此Java專門提供了一個類型檢查的關鍵字instanceof,使用格式形如“A instanceof B”,意思是檢查A實例是否屬於B類型,該表達式返回true表示屬於,返回false表示不屬於。這樣關於雞類實例的類型判斷,借助於新關鍵字instanceof,又有了第三個鑒別辦法,詳細的鑒別代碼如下所示:

	// 利用關鍵字instanceof檢查某實例的歸屬類
	private static void checkInstance(Chicken chicken) {
		if (chicken instanceof Cock) { // 判斷這只雞是不是公雞
			System.out.println("檢查對象實例:這是只公雞。");
		} else if (chicken instanceof Hen) { // 判斷這只雞是不是母雞
			System.out.println("檢查對象實例:這是只母雞。");
		} else {
			System.out.println("檢查對象實例:這既不是公雞也不是母雞。");
		}
	}

可見利用instanceof判斷實例的類型,不但簡化了代碼的寫法,而且看起來也更易懂了。



更多Java技術文章參見《Java開發筆記(序)章節目錄》

Java開發筆記(五十二)對象的類型檢查