Java語言和標準庫功能強大,但功能強大, 責任重大 。 一方面看到很多用戶代碼濫用或濫用稀有的Java功能,另一方面卻完全忘記了大多數基本功能之后,我決定撰寫此摘要。 這不是每個Java開發人員都應該探索,了解和使用的要求和領域的列表。 相反! 我將Java功能分為三類: 日常 , 偶爾和從不(僅框架和庫) 。 規則很簡單:如果您發現自己經常使用給定功能,然后建議使用該功能,則可能是工程過度或試圖構建過于籠統且可重復使用的功能。 如果您沒有足夠頻繁地使用給定功能(根據我的主觀清單),則可能會錯過一些真正有趣且重要的機會。
請注意,我只關注Java,JVM和JDK。 我不建議您使用哪些框架以及使用的可能性。 我還假設了典型的服務器端面向業務的應用程序。
日復一日
假定每天都要使用Java語言的以下功能。 如果您從未見過它們,或者很少使用它們,則可以仔細看看,它們確實很有幫助:
- 類,接口,包 –認真。 將您的代碼放在類中。 您還記得大學時曾說過,類是封裝的數據+對數據起作用的方法嗎? 僅具有狀態的類幾乎不是一個結構。 僅包含方法的類只是一個包含函數的名稱空間。 必要時也請使用接口。 但是在創建僅具有一個實現的接口之前,請三思而后行。 也許您不需要中間人? 但是,請遵循完善的命名約定將所有內容打包放入軟件包中。
- 靜態方法 –不要害怕它們。 但是,僅將它們用于無狀態實用程序方法。 永遠不要在
static
方法中編碼任何業務邏輯。 -
ExecutorService
–線程池 –必須創建并有效使用線程池,了解排隊和Future<T>
工作方式。 不要重新實現線程池,每當有人說生產者-消費者時都要考慮一下它們。 -
Atomic
-*系列 –不要使用synchronized
來勉強讀取/更新某些計數器或原子引用。Atomic
*系列類使用有效的比較和交換低級指令來達到驚人的效率。 確保您了解這些類提供的保證。 - 設計模式 –從技術上講不是Java語言的一部分,而是必不可少的。 您應該,知道,了解和使用它們,但要謹慎而謹慎。 就像使用界面一樣-不要太過分。 GoF甚至EI模式通常應出現在代碼庫中。 但是,讓模式出現在您的思維過程中,而不是讓思維過程受模式驅動。
- 內置集合(包括并發集合) –您絕對必須了解并使用內置集合,并了解
List
,Map
和Set
之間的區別。 使用線程安全的集合對您來說不是問題。 了解性能特征并對其背后的實現進行基本概述。 這真的很基本。 還知道并使用各種BlockingQueue
實現。 并發很困難,不要自己重新實現其中的一些東西就更難了。 - 內置的注釋 -注釋是在這里留下來,學會使用
@Override
(和@Deprecated
在一定程度上)每天一致。 - 異常 –使用未經檢查的異常來表示異常,異常失敗,需要采取措施。 了解如何處理受檢查的異常。 學習閱讀堆棧跟蹤。
- 嘗試使用資源 –熟悉這種神話般的語言構造。 如果您的班級需要任何清理,請實施
AutoCloseable
。 - 阻止IO –使用
Reader
/Writer
,InputStream
/OutputStream
類是您應該真正熟悉的東西。 理解它們之間的區別,不用擔心就使用緩沖和其他裝飾器。
這將結束您應使用的日常工具的列表。 如果您從未聽說過或僅偶爾使用過它們,請仔細研究它們,因為它們可能會成為您的救星。
偶爾
以下是您不應該害怕使用的語言功能,但也不應濫用它們。 如果您發現自己每天都在利用它們,或者在午餐前幾次看到這些功能,那么您的設計可能有問題。 我從后端企業Java開發人員的角度來看。 這些類型的功能很有用,但不太常用。
- 繼承和抽象類 –實際上,事實證明,我不經常使用繼承,而且我也不是很想念它。 由接口驅動的多態性要靈活得多,尤其是在Java中缺乏特性的情況下。 比起繼承,也更喜歡組合 。 太多級別的繼承會導致代碼難以維護。
- 正則表達式 – 有些人遇到問題時會認為“我知道,我會使用正則表達式”。 現在他們有兩個問題。 。 沒有正則表達式的世界將更加無聊和麻煩。 它們對于解析常規語言(而不是HTML )非常有用,但是它太容易過度使用了。 如果您發現自己整天都在正則表達式之前進行制作,測試,修復和維護,則可能是在使用錯誤的工具來完成這項工作。 我一直以來最喜歡的:
public static boolean isNegative(int x) {return Integer.toString(x).matches('-[0-9]+'); }
-
Semaphore
,CountDownLatch
,CyclicBarrier
等 –與infomouswait()
/notify()
對相比,它們在一個數量級上都非常有用。 但是即使濫用它們,也不會阻止您出現并發錯誤。 當您經常看到這些同步機制時,請考慮線程安全的集合或某些框架。 - 用戶代碼中的泛型類型 –使用內置集合和具有泛型類型的其他類不僅應該是日常實踐,而且對您來說應該顯而易見。 但是我的意思是自己開發代碼,以獲取或返回通用類型。 像這樣:
public <T, F> ContractValidator<T extends Contract> T validate(Validator<T>, F object)
有時有必要在您自己的代碼中使用泛型,但不要太meta- 。 當然,靜態類型和類型安全應該是您的首要任務,但是也許您可以避免使用太多的泛型,復雜類型?
- JVM中的腳本語言 –您知道JDK具有內置JavaScript解釋器嗎? 而且您幾乎可以插入其他任何語言,例如Groovy或JRuby? 有時,將小腳本嵌入應用程序中更為簡單,即使客戶也可以更改。 這種情況并不常見,但是在瞬息萬變的市場中,重新部署可能不是一種選擇。 只需記住,如果腳本代碼的總行數超過代碼總數的1%,則應開始擔心維護。
- Java NIO –很難做到正確,甚至很難從中受益。 但是在極少數情況下,您實際上必須使用NIO壓縮盡可能多的性能和可伸縮性。 但是,更喜歡可以為您執行此操作的庫。 同樣在正常情況下,阻塞IO通常就足夠了。
-
synchronized
關鍵字 –出于簡單原因,您不應過于頻繁地使用它。 它使用的次數越多,執行的頻率就越高,從而影響性能。 請考慮使用線程安全的集合和原子原始包裝器。 還要確保您始終了解哪個對象用作互斥體。
我認為上述功能很有價值且很重要,但不一定每天都在起作用。 如果您每天都看到其中的任何一個,則可能表示設計過度設計或……經驗不足的開發人員。 經驗帶來簡單。 但是,您可能也有非常不同的要求,這也適用于第三組。
永不(請考慮:僅框架和庫開發人員)
您應該了解并理解以下功能背后的原理,以便了解框架和庫。 而且您必須了解它們以有效地為我們服務,我認為如果有問題的人只是閱讀所用庫的代碼,就可以避免有關StackOverflow的太多問題。 但是理解并不意味著使用。 您幾乎永遠都不要直接使用它們,它們大多是高級的,骯臟的和復雜的。 即使出現這種功能,也可能導致嚴重的頭痛。
- 套接字 –認真地說,套接字。 您必須了解TCP / IP堆棧的工作原理,在線程方面要非常自覺,在解釋數據時要小心,對流保持警惕。 遠離使用純套接字,有數百個將它們包裝起來并提供更高級別抽象的庫– HTTP,FTP,NTP,SMB,電子郵件…(例如,請參見Apache Commons net )。 您會驚訝于編寫體面的HTTP客戶端或服務器有多么困難。 而且,如果您需要為某些專有協議編寫服務器,請絕對考慮使用Netty 。
- 反思 –在業務代碼中沒有內省類和方法的地方。 框架離不開反思,我離不開。 反射會使您的代碼變慢,不安全且難看。 通常,AOP就足夠了。 我什至會說傳遞
Class<T>
實例是一種代碼味道。 - 動態代理和字節碼操作 –
Proxy
類很棒,但就像反射一樣,僅應由支持您的框架和庫使用。 它們是輕量級AOP的基本構建塊。 如果您的業務應用程序(不是框架或庫,甚至Mockito都使用這些技術!)需要字節碼生成或操作(例如ASM或CGLIB )–你陷入了深淵我會為你祈禱。 - 類加載器 –與類加載器有關的所有內容。 您必須了解它們,層次結構,字節碼等。但是,如果您編寫自己的類加載器,那將是通往地獄的道路。 并不是說它是如此復雜,但是它可能是不必要的。 留給應用服務器。
-
Object.html#clone()
–老實說,我不記得我是否在整個(Java開發人員)生命中都使用過這種方法。 我只是……沒有……而且我找不到使用它的任何理由。 我要么有一個顯式的復制構造函數,要么更好地使用不可變對象。 您有任何合法的用例嗎? 好像是1990年代... - 本機方法 – JDK中有一些方法 ,即使對于諸如計算正弦函數之類的小任務也是如此。 但是Java不再是全班最慢的孩子,實際上恰恰相反。 另外,我無法想象使用標準庫或第三方庫無法實現哪種邏輯。 最后,本機方法很難正確解決,您會遇到低級的,令人討厭的錯誤,尤其是在內存管理方面。
- 自定義集合 -遵循原始JavaDoc中定義的所有合同實施全新集合非常困難 。 像Hibernate這樣的框架使用特殊的持久化集合。 很少需要一個針對您的需求的集合,以至于內置集合都不夠好。
-
ThreadLocal
–庫和框架經常使用線程局部變量。 但是出于兩個不相關的原因,您永遠不要嘗試利用它們。 首先,ThreadLocal
通常是您想潛入的隱藏半全局參數。 這使您的代碼難以推理和測試。 其次,如果未正確清理ThreadLocal
很容易引入內存泄漏(請參閱this , this , this和this和…) - WeakReference和SoftReference –這些類是相當低級的,在實現與垃圾回收良好配合的緩存時非常有用。 幸運的是,有很多開源緩存庫,因此您不必自己編寫。 了解這些類的作用,但不要使用它們。
-
com.sun.*
和sun.*
軟件包,尤其是sun.misc.Unsafe
–遠離這些軟件包,只是……不要去那里。 沒有理由探索這些專有的,未記錄的文檔,并且不能保證保留向后兼容的類。 只是假裝他們不在那里。 為什么要使用Unsafe
?
當然,上面的列表是完全主觀的,很可能不是確定的。 如果您認為某些物品放置在錯誤的位置或完全丟失了某些物品,建議您提出評論和建議。 我想構建一個摘要,可以在代碼審查期間或評估項目時作為參考。
參考: Java具有 JCG合作伙伴 Tomasz Nurkiewicz在Java及社區博客上的適用性 。
翻譯自: https://www.javacodegeeks.com/2012/10/java-features-applicability.html