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

来源:https://www.cnblogs.com/pinlantu/archive/2019/01/23/10311824.html
-Advertisement-
Play Games

前面介紹了類的多態性,來自於雞類的實例chicken,既能用來表達公雞實例,也能用來表達母雞實例。可是這導致了一個問題,假如在call方法內部需要手工判斷輸入參數屬於公雞實例還是母雞實例,那該如何是好?所謂“雄兔腳撲朔,雌兔眼迷離,雙兔傍地走,安能辨我是雄雌”,固然編譯器在運行之時能夠自動判斷這是哪 ...


前面介紹了類的多態性,來自於雞類的實例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開發筆記(序)章節目錄


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 使用static關鍵字修飾的變數和方法為靜態變數、靜態方法。 非靜態方法可以訪問靜態變數/方法和非靜態變數/方法,但靜態方法只能訪問靜態變數/方法。 可以看到在靜態方法中調用非靜態變數和非靜態方法時,Java會報錯。 所謂的靜態是指變數或方法可以不依賴對象而直接使用類名來調用,這也是static的意 ...
  • 第74節:第74節:Java中的Cookie和Session : 什麼是 ,有什麼用哦,怎麼用呢? 啟動伺服器後,會給每個應用程式創建一個 ,並且這個 對象只有一個。可以用於獲取全局參數,工程下的資源,和存取數據,共用數據。 例子,如何獲取全局參數,如何獲取工程下的資源,如何進行存取數據,用例子代碼 ...
  • 今天在寫條件語句時,一老出錯 自認為程式上是沒什麼問題的,所以將逗號去掉試試看 得出了正確的值,很意外,然後多試了幾次之後,逗號也可以輸入了 原來我誤把中文輸入法的逗號輸入到scanf中,而運行時又用英文輸入法 然後得出來的總結就是,scanf函數中必須用自己制定的格式,輸入,輸出。 ...
  • If I had only one hour to save the worlds,I would spend fifty five minutes defining the problem,and only five minutes finding the solution. 如果我只有1小時拯救 ...
  • 函數名的使用: 函數名可以作為值,賦值給變數 函數名可以作為參數傳參給函數. 函數名可以作為返回值 函數名可以作為元素存儲在容器里 閉包:在嵌套函數內,使用外層局部變數(非全局變數)就是一個閉包,閉包可以多層嵌套.閉包的優點: 避免局部變數不被外界修改 函數生命周期延長 節省開闢空間,銷毀空間的時間 ...
  • 一、前言 在上一篇文章中,已經介紹了基於Redis實現分散式鎖的正確姿勢,但是上篇文章存在一定的缺陷——它加鎖只作用在一個Redis節點上,如果通過sentinel保證高可用,如果master節點由於某些原因發生了主從切換,那麼就會出現鎖丟失的情況: 於是,客戶端1和客戶端2同時持有了同一個資源的鎖 ...
  • 如果你不懂電腦語言,那麼就請你不要說你是學電腦的!!好丟人的。。。今天然我帶你深入瞭解真正的電腦語言! 編程語言可分為三種:高級語言、彙編語言、機器語言。 1、什麼是高級語言? 高級語言:它是把高級語言的基本結構和語句與低級語言的實用性結合起來的工作單元。 常見的高級語言:Java、C、C++ ...
  • 1、實現基本CRUD功能 使用MyBatis對數據完整的操作,也就是CRUD功能的實現。根據之前的內容,要想實現CRUD,只需要進行映射文件的配置。 範例:修改EmpMapper.xml文件,實現CRUD 此時已經完成了映射文件的配置。就可以利用SqlSession類對象完成具體的操作,方法如下: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...