開發者應該避免使用的6個Java功能
本文作者是一名擁有多年Java開發經驗的程式設計師,他從經驗中得出,並不是所有的Java SE功能/API都值得程式設計師去使用,比如本文列舉的這6個,大家在使用前得慎重對待。以下是對原文的摘譯。
多年的Java開發經驗告訴我,從長遠角度來看,以下這些Java SE功能/API,開發者最好停止使用。
- Reflection
- Bytecode manipulation
- ThreadLocals
- Classloaders
- Weak/Soft references
- Sockets
1.Reflection
Reflection即反射,在許多流行的庫裡面都有反射機制,比如Spring和Hibernate。通過對業務程式碼進行反思,我建議大家避免使用反射。下面列出我反對使用的原因:
首先涉及到程式碼可讀性/工具支援。開啟IDE並且在Java程式碼裡找到相互依賴關係。使用relection替換方法呼叫,並且試著重複該步驟。事情變的愈發不可收拾,正常情況下都應該封裝好了再修改狀態。下面來看看具體程式碼示例:
public class Secret { private String secrecy; public Secret(String secrecy) { this.secrecy = secrecy; } public String getSecrecy() { return null; } } public class TestSecrecy { public static void main(String[] args) throws Exception { Secret s = new Secret("TOP SECRET"); Field f = Secret.class.getDeclaredField("secrecy"); f.setAccessible(true); System.out.println(f.get(s)); } }
通過檢視以上程式碼可以得知,方法getDeclaredField()引數只有在執行時才可以被發現。而你也清楚,執行時產生的bug總比不執行指令碼要更加棘手。
其次,反射呼叫優化是由JIT執行的,一些優化可能需要花費很長時間才能得到應用,而有些優化甚至都得不到應用,所以關於反射的效能優化有時會被數量化。但在一個典型的業務應用程式中——你可能不會真正意識到這些效能開銷。
總之,開發者應該通過AOP合理地在業務層使用反射,除此以外,你最好離它遠遠的。
2.Bytecode manipulation.
位元組碼操作,如果我看到你在Java EE應用程式裡直接使用CGLIB或ASM,我可能會立即跑開。
最糟糕的事情莫過於在編譯期間沒有任何可執行的程式碼。實際上,當產品在執行時,你根本不知道哪塊程式碼在執行。所以,當你遇到麻煩時,會自然地把錯誤拋給執行時故障排除和除錯,不過這樣反而會更麻煩。
3.ThreadLocals
這裡有兩個不相關的原因,當我在業務層程式碼裡看到ThreadLocals時會顫抖。首先,在ThreadLocals的幫助裡,你可能會看到許多變數的使用都沒有通過方法呼叫鏈來明確地向下傳遞。這在某些場合下是有用的,但當你一旦粗心,你會在程式碼裡構建許多意料不到的依賴關係。
第二個不相關的原因與我日常的工作相關,在ThreadLocals裡儲存資料會引發記憶體洩露。最起碼我遇到的Permgen洩露有十分之一都是使用ThreadLocals造成的,在結合了類載入器和執行緒池後,“java.lang.OutOfMemoryError:Permgen space”異常可能就馬上出現了。
4.Classloaders
首先,類載入器是一個複雜的野獸。你必須先了解它的層次結構、委託機制、類快取等等。即使你認為自己已經掌握了,它可能還是不能正常工作。最終將導致一個類載入器洩露問題。因此我只能建議你將這個任務留給應用伺服器處理
5.Weak/Soft references
現在,你應該更好的理解Java的內部方法。使用軟引用來重寫所有的快取並不明智。我知道,當你手上拿著錘子的時候,就會到處尋找釘子。可對於錘子來說,快取並不是個好釘子。為什麼?基於軟引用構建快取可能是如何委託一些複雜因素到GC而不是通過自身實現的一個好例子。
下面舉個快取的例子,你使用軟引用來建立資料,當記憶體被耗盡時,GC進入並且進行清理。但是,快取中被刪除的物件並未得到你的控制,而且很有可能在下一次的cache-miss中重新建立。如果記憶體仍然不足,你可以觸發GC進行再次清理。你可能已經看出了整個執行過程的惡性迴圈,整個應用程式就變成了CPU與GC不斷執行的狀態了
6.Sockets
普通老式的java.net.Socket實在是太複雜,以至於很難弄正確。我覺得阻塞性是其根本性的缺陷。當你編寫一個典型的帶有Web前端的Java EE應用程式時,應用程式需要高併發度來支援大量的使用者,而你現在最不想發生的是不具有可擴充套件的執行緒池坐等阻塞套接字。
目前有許多精彩可用的第三方庫,使用它們可以更好的完成任務,比如Netty,開發者不妨嘗試下。
來自:Plumbr
相關文章
- 有趣的探索:每個遊戲開發者應該避免用的6種老掉牙設定遊戲開發
- 使用 Docker 容器應該避免的 10 個事情Docker
- 每個Android開發者應該知道的6個SDK和APIAndroidAPI
- 你應該遠離的6個Java特性Java
- 每個 Java 開發者都應該知道的 5 個註解Java
- 每個Java開發者都應該知道的5個JDK工具JavaJDK
- 專業Web設計師應該避免的6個關鍵錯誤Web
- 每個 Java 開發者應該知道(並愛上)的 8 個工具Java
- 新手Web設計師應該避免的 6 宗罪Web
- WEB 開發者應該具備的 6 大技能?Web
- 好的web開發者應該10個技巧Web
- 每個開發者都應該使用的VSCode外掛 - tvkoushikVSCode
- C++開發者都應該使用的10個C++11特性C++
- 每個C++開發者都應該使用的十個C++11特性C++
- 每個PHP開發者都應該看的書PHP
- 每個開發者都應該知道的33個JavaScript概念JavaScript
- 三件Java開發者應該知道的事兒Java
- 為什麼每個Android開發者都應該使用AnkoAndroid
- 您現在應該開始使用的 10 個 PHP 8.1 功能PHP
- 開發者應該掌握的3個發行步驟
- 每個MySQL開發者都應該瞭解的10個技巧MySql
- Web前端開發應該避免的幾個思維誤區Web前端
- 學習 MySQL 應該掌握的 6 個技巧MySql
- C# 中 10 個你真的應該學習(和使用!)的功能C#
- [譯]iOS開發者在Swift中應避免過度使用@objciOSSwiftOBJ
- WEB開發者應該反問自己的10個問題Web
- Apple Search Ads投放中,應該避免的7個誤區APP
- Java開發者應該列入年度計劃的5件事Java
- Java開發者應該知道的五款錯誤跟蹤工具Java
- 五種應該避免的程式碼註釋
- 使用 Vue 3 時應避免的 10 個錯誤Vue
- 微服務應該避免協調成本微服務
- 重要!每個開發者都應該掌握的9個核心演算法演算法
- 你應該知道的10件關於Java 6的事情Java
- 一個開發者的使命感究竟應該是什麼?
- 成功部署CRM應該考慮的6個原則
- 避免在Java 介面中使用陣列的3 個理由Java陣列
- 避免在Java介面中使用陣列的3個理由Java陣列