Java开发中更多常见的危险信号
在《 Java開發中的常見危險信號》一文中,我研究了一些不一定本身就是錯誤或不正確的做法,但它們可能表明存在更大的問題。 這些“紅色標記”類似于“代碼氣味”的概念,我在這篇文章中引用的某些特定“紅色標記”被稱為“代碼氣味”。 正如我在第一篇文章中所述,這些“紅色標志”中的幾個被認為足夠重要,以至于靜態代碼分析工具和Java IDE會對其進行標記。
直接“記錄”消息到stdout或stderr
日志記錄框架已經在Java中使用了很長時間,如今,我們擁有各種各樣的日志記錄框架 (其中一些框架是相互構建的),包括傳統的Log4j 1.2 , log4j 2 , java.util.logging ( Java Logging API ), Apache Commons Logging和SLF4J 。 鑒于此,當我在Java代碼中看到System.out和System.err引用時,我感到很驚訝。
有許多原因直接引起人們關注是否存在直接寫入標準輸出或標準錯誤的Java代碼。 引起關注的一個原因是,這可能意味著不成熟的代碼,該代碼原本打算在以后更改為日志記錄,但卻沒有得到最終的關注。 引用標準輸出和標準錯誤的另一個缺點是,“已記錄”消息可能不會出現在日志文件中,而其余日志則由日志框架編寫。 第三個問題是,日志記錄框架提供了許多不錯的功能,而簡單地寫入標準輸出和標準錯誤并沒有提供這些功能。 這些功能包括輕松控制所記錄消息的級別的能力,在指定的記錄級別下控制是否通過性能降低來生成大型輸出字符串的功能,輕松將捕獲的異常與已記錄的錯誤消息相關聯的功能,并且能夠輕松地將輸出重定向到不同的目的地和格式。 盡管所有這些都可以在直接處理輸出和錯誤流時手動完成,但它需要自定義工作,而不是“開箱即用”。
除了使用System.out和System.err直接訪問外,Java代碼中還存在一些寫入標準輸出和標準錯誤的表現形式(盡管它們通常隱式包含System.out和System.err )。 例如, Throwable.printStackTrace() [更常用于Exception的處理],正如其Javadoc所言:“將此throwable及其回溯打印到標準錯誤流中。”
使用StringBuffer而不是StringBuilder
這誠然是一個很小的事情,但它可以指示過時的 Java代碼( StringBuffer的推出在JDK 1.0和StringBuilder的介紹在J2SE 5 )或Java代碼在開發商沒有明白之間的差別的StringBuffer和StringBuilder的 。 在大多數情況下,兩者之間的性能差異對于手頭的應用程序并不重要,但是由于StringBuilder在大多數我使用StringBuffer的 情況下更可取 ,因此人們也可能會享受使用StringBuilder通常帶來的輕微性能優勢。 我有困難的時候,回顧一個實例中,我所看到StringBuffer使用其中StringBuilder不可能被替代。 一個相關的危險信號是在其構造函數或重載的append方法中將String串聯與StringBuilder混合 。
方法和構造函數中的參數過多
當方法或構造函數的參數過多時,尤其是在多個參數具有相同類型的情況下,我總是擔心其客戶端無法正確使用該方法或構造函數。 例如,如果一個方法接受三個String和三個boolean ,則客戶端很容易混淆傳入的特定值。在這種情況下,編譯器無濟于事,這是檢測問題根源的唯一方法(甚至根本不存在問題)在運行時(通過單元測試或其他測試,或者可悲的是,在軟件的常規執行過程中)。 對于不正確的設計,太多的參數也可能成為“危險信號”。 我不會在本文中更深入地討論這個“紅色標志”,因為我已經介紹了這個“紅色標志”,多種解決方法,并在一系列八篇博客文章中介紹了它。
- Java方法中的參數太多,第1部分:自定義類型
- Java方法中的參數太多,第2部分:參數對象
- Java方法中的參數太多,第3部分:構建器模式
- Java方法中的參數太多,第4部分:重載
- Java方法中的參數太多,第5部分:方法命名
- Java方法中的參數太多,第6部分:方法返回
- Java方法中的參數太多,第7部分:可變狀態
- Java方法中的參數太多,第8部分:工具
過多的顯式投射
顯式轉換可能是危險信號情況的最佳示例之一,在該情況下,轉換本身可能不會影響正常工作的任何功能或邏輯,但是提示情況不盡如人意。 強制轉換可能意味著較差的設計選擇(例如,未正確使用多態性,在不適當的情況下使用繼承,或迫使從未設計過的東西放在一起)。 在許多情況下(例如,在獲取Spring Framework上下文bean時),顯式強制轉換當然是適當的或必需的,但是顯式強制轉換也可以用作拐杖,以使未經過精心設計的工作正常進行。 強制轉換還可以指示過于寬泛的API或過于寬泛的API中使用的接口(在下一項中突出顯示)。
接口或類的使用范圍太廣
當Set或List或更具體的接口更合適時,我經常看到Collection接口用作方法參數或返回類型。 例如,一個返回Collection但希望客戶端代碼知道返回的Collection是有序的方法,應該返回List或更具體的接口或List實現。 同樣,如果某個方法需要一個有序的Set ,則它應該將該方法宣傳為希望有SortedSet或類似的接口或實現類。 對于給定的合同,當返回或期望作為參數的接口或類太寬泛時,有人被迫“知道”這種情況,并強制轉換為適當的級別以獲取他們所依賴的功能。
使用適當的級別或接口或類不僅可以避免不必要的顯式轉換。 適當的類型級別比單純的文檔可以更好地宣傳和執行方法合同。 但是,它遠不止于此。 在某些情況下,當公告的接口太寬而無法捕獲方法協定中的假設時,可能會發生重大的運行時異常。 例如,一個通用接口可以選擇支持一個方法,但是該接口的實際實現在被調用時會拋出UnsupportedOperationException ,因為它沒有實現該可選方法。 在UnsupportedOperationException和ClassCastException之間,使用過寬的接口或類可能會導致潛在的嚴重運行時問題。
這并不是說應該避免使用接口或廣泛的類。 而是說,應該在返回類型和參數類型中使用適當的抽象度,以便適當地宣告和強制執行調用雙方的預期行為。
使用List.addAll()
使用重載的List.addAll()方法之一會讓我感到緊張,當我在代碼中看到它時,它會亮紅色。 這并不意味著使用它總是錯誤的,但是似乎由于濫用它,我似乎已經看到了很多腫的內存問題。 因為List會添加開發人員喜歡的“重復”對象,所以錯誤的代碼可以用冗余對象以指數方式填充這些List 。 此范圍的負面影響從潛在的性能障礙到內存不足。 當我看到使用List.addAll() ,我會仔細檢查代碼并對其進行單元測試,以確保其內存消耗不會失控。 如前面的“紅色標記”中所述,必須對Collection.addAll()任何使用進行類似于List.addAll()分析,直到可以肯定地知道Collection實際上不是List為止。
非Java方言
也許對我而言,最好的例子是“危險信號”,這是與“普遍接受的Java編碼標準 ”相反或有明顯不同的慣用語和代碼約定的頻繁使用。 使用名稱,大小寫或其他樣式問題都不會直接影響代碼的正確性或性能。 但是,這些差異仍然是“危險信號”,警告邏輯或性能方面的潛在實際問題,因為使用這些嚴重的非標準習語和約定意味著開發人員可能是Java的新手,因此可能犯了一些新的錯誤。 Java。 關于“不帶重音”編寫Java代碼的重要性的好文章是講不帶重音的Java語言 。 在該文章中,作者Elliotte Rusty Harold撰寫了有關如何更難以閱讀和維護此類代碼的文章。
在相對罕見的情況下,這可能會從樣式問題變為影響問題。 當人們以一種在另一種語言(例如C或C ++)中最有意義的方式編寫Java代碼,但沒有Java的替代方法那樣有意義時,就會發生這種情況。
結論
就像我在第一篇有關Java代碼中的紅色標志的文章中一樣,本文中討論的“紅色標志”通常是指在適當和特定的情況下使用時不一定正確的事物,但通常確實表明事物不那么正確因為它們可能會在更大的應用程序中使用。
翻譯自: https://www.javacodegeeks.com/2013/12/more-common-red-flags-in-java-development.html
總結
以上是生活随笔為你收集整理的Java开发中更多常见的危险信号的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 笔记本电脑如何连接投影电脑如何连接到投影
- 下一篇: 新华三路由器NTP怎么配置h3路由器如何