日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java微妙_编码Java时的10个微妙的最佳实践

發布時間:2023/12/3 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java微妙_编码Java时的10个微妙的最佳实践 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

java微妙

這是10條最佳實踐的列表,這些最佳實踐比您的平均Josh Bloch有效Java規則要微妙得多。 盡管Josh Bloch的列表很容易學習,并且涉及日常情況,但此處的列表包含了涉及API / SPI設計的較不常見的情況,盡管這些情況可能會產生很大的影響。

我在編寫和維護jOOQ時遇到了這些問題, jOOQ是Java中的內部DSL建模SQL。 作為內部DSL,jOOQ最大限度地挑戰了Java編譯器和泛型, 將泛型,可變參數和重載組合在一起,這是Josh Bloch可能不推薦使用的“平均API”。

讓我與您分享編碼Java時的10個微妙的最佳實踐:

1.記住C ++析構函數

還記得C ++析構函數嗎? 沒有? 然后,您可能會很幸運,因為您無需再調試任何代碼,因為在刪除對象后未釋放分配的內存,從而不會導致內存泄漏。 感謝Sun / Oracle實現垃圾回收!

但是,銷毀者對他們具有一個有趣的特征。 通常以相反的順序釋放內存是有意義的。 在使用類似析構函數的語義進行操作時,也要在Java中記住這一點:

  • 當使用@Before和@After JUnit批注時
  • 分配時,釋放JDBC資源
  • 調用超級方法時

還有各種其他用例。 這是一個具體示例,顯示了如何實現某些事件偵聽器SPI:

@Override public void beforeEvent(EventContext e) {super.beforeEvent(e);// Super code before my code }@Override public void afterEvent(EventContext e) {// Super code after my codesuper.afterEvent(e); }

另一個臭名昭著的餐飲哲學家問題就是一個很好的例子,說明了為什么這很重要。

餐飲哲學家。 在這里看到: http : //adit.io/posts/2013-05-11-The-Dining-Philosophers-Problem-With-Ron-Swanson.html

規則 :無論何時使用before / after,allocate / free,take / return語義實現邏輯,請考慮after / free / return操作是否應按相反的順序執行操作。

2.不要相信您早期的SPI發展判斷

向消費者提供SPI是允許他們將自定義行為注入您的庫/代碼中的簡便方法。 不過請注意,您的SPI演變判斷可能會欺騙您,使您認為您(不需要)該附加參數 。 確實, 不應及早添加任何功能。 但是一旦發布了SPI,并決定遵循語義版本控制 ,當您意識到在某些情況下可能還需要另一個參數時,您會后悔自己在SPI中添加了一個愚蠢的單參數方法:

interface EventListener {// Badvoid message(String message); }

如果還需要消息ID和消息源怎么辦? API的發展將阻止您輕松地將該參數添加到上述類型。 使用Java 8,您可以添加防御者方法來“捍衛”您不良的早期設計決策:

interface EventListener {// Baddefault void message(String message) {message(message, null, null);}// Better?void message(String message,Integer id,MessageSource source); }

注意,不幸的是,防御者方法不能定為final 。

但是,比使用數十種方法污染SPI更好的方法是,僅為此目的使用上下文對象(或參數對象) 。

interface MessageContext {String message();Integer id();MessageSource source(); }interface EventListener {// Awesome!void message(MessageContext context); }

與EventListener SPI相比,您可以更輕松地開發MessageContext API,因為實施該應用程序的用戶將更少。

規則 :無論何時指定SPI,都應考慮使用上下文/參數對象,而不要編寫帶有固定數量參數的方法。

備注 :通常也可以通過專用的MessageResult類型(可以通過構建器API構造)來傳遞結果,這是一個好主意。 這將為您的SPI增加更多的SPI演進靈活性。

3.避免返回匿名,本地或內部類

Swing程序員可能有幾個鍵盤快捷鍵可以為其數百個匿名類生成代碼。 在許多情況下,創建它們很不錯,因為您可以本地遵守接口,而無需經歷思考完整SPI子類型生命周期的“麻煩”。

但是,您不應該過于頻繁地使用匿名,局部或內部類,原因很簡單:它們保留對外部實例的引用。 并且,如果您不小心,它們會將外部實例拖到任何地方,例如,拖到本地類之外的某個范圍。 這可能是內存泄漏的主要來源,因為整個對象圖會突然以微妙的方式糾纏在一起。

規則 :每當您編寫匿名,本地或內部類時,請檢查是否可以使其成為靜態類,甚至是常規頂級類。 避免將匿名,本地或內部類實例從方法返回到外部作用域。

備注 :對于簡單對象實例化,圍繞雙花括號有一些聰明的做法:

new HashMap<String, String>() {{put("1", "a");put("2", "b"); }}

這利用了JLS§8.6中指定的 Java實例初始化程序 。 看起來不錯(也許有點奇怪),但確實是個壞主意。 原來是完全獨立的HashMap實例現在將保留對外部實例的引用,無論發生什么情況。 此外,您將創建一個額外的類供類加載器管理。

4.立即開始編寫SAM!

Java 8正在敲門。 隨Java 8一起提供lambda ,無論您是否喜歡。 不過,您的API使用者可能會喜歡它們,因此您最好確保他們可以盡可能多地使用它們。 因此,除非您的API接受簡單的“標量”類型(例如int , long , String , Date ,否則您的API應盡可能多地接受SAM。

什么是SAM? SAM是單一抽象方法[Type]。 也稱為功能接口 ,很快將使用@FunctionalInterface注釋進行注釋 。 這與規則2配合得很好,其中EventListener實際上是SAM。 最好的SAM是具有單個參數的SAM,因為它們將進一步簡化lambda的編寫。 想象寫作

listeners.add(c -> System.out.println(c.message()));

代替

listeners.add(new EventListener() {@Overridepublic void message(MessageContext c) {System.out.println(c.message()));} });

想象一下通過jOOX進行的 XML處理,它具有幾個SAM:

$(document)// Find elements with an ID.find(c -> $(c).id() != null)// Find their child elements.children(c -> $(c).tag().equals("order"))// Print all matches.each(c -> System.out.println($(c)))

規則 :與您的API使用者保持友好, 現在已經編寫SAM /功能接口。

備注 :有關Java 8 Lambda和改進的Collections API的一些有趣的博客文章可以在這里找到:

  • http://blog.informatech.cr/2013/04/10/java-optional-objects/
  • http://blog.informatech.cr/2013/03/25/java-streams-api-preview/
  • http://blog.informatech.cr/2013/03/24/java-streams-preview-vs-net-linq/
  • http://blog.informatech.cr/2013/03/11/java-infinite-streams/

5.避免從API方法返回null

我曾經寫過一兩次關于Java的NULL的博客。 我還寫了關于Java 8的Optional簡介的博客。 從學術和實踐的角度來看,這些都是有趣的話題。

雖然NULL和NullPointerExceptions可能會在Java中困擾一段時間,但是您仍然可以以不會讓用戶遇到任何問題的方式設計API。 盡可能避免從API方法返回null。 您的API使用者應能夠在適用的情況下鏈接方法:

initialise(someArgument).calculate(data).dispatch();

在以上代碼段中,所有方法均不應返回null。 實際上,通常使用null的語義(缺少值)應該是非常例外的。 在諸如jQuery (或jOOX ,其Java端口)之類的庫中,由于始終對可迭代對象進行操作 ,因此完全避免了null。 是否匹配某項與下一個方法調用無關。

由于延遲初始化,通常還會出現空值。 在許多情況下,也可以避免延遲初始化,而不會對性能產生任何重大影響。 實際上,僅應謹慎使用惰性初始化。 如果涉及大型數據結構。

規則 :盡可能避免從方法返回null。 僅對“未初始化”或“缺少”的語義使用null。

6.切勿從API方法返回空數組或列表

雖然在某些情況下從方法返回null可以,但絕對沒有用過返回null數組或null集合的用例! 讓我們考慮一下丑陋的java.io.File.list()方法。 它返回:

在此抽象路徑名表示的目錄中命名文件和目錄的字符串數組。 如果目錄為空,則數組為空。 如果此抽象路徑名不表示目錄,或者發生I / O錯誤,則返回null。

因此,處理此方法的正確方法是

File directory = // ...if (directory.isDirectory()) {String[] list = directory.list();if (list != null) {for (String file : list) {// ...}} }

空檢查真的必要嗎? 大多數I / O操作都會產生IOException,但是此操作將返回null。 Null無法保存任何指示為什么發生I / O錯誤的錯誤消息。 因此,這在三種方式上是錯誤的:

  • 空無助于發現錯誤
  • Null不允許將I / O錯誤與不是目錄的File實例區分開
  • 每個人都會忘記空值

在集合上下文中,“空缺”的概念最好通過空數組或集合來實現。 除了再次進行延遲初始化外,幾乎沒有有用的數組或集合。

規則 :數組或集合絕不能為空。

7.避免狀態,發揮作用

HTTP的優點在于它是無狀態的。 所有相關狀態都在每個請求和每個響應中傳遞。 這對于REST的命名至關重要: 代表性狀態轉移 。 當用Java完成時,這也很棒。 當方法接收有狀態參數對象時,可以根據規則2來考慮它。 如果狀態是在這樣的對象中傳遞的,而不是從外部操縱的,那么事情會變得非常簡單。 以JDBC為例。 下面的示例從存儲過程中獲取游標:

CallableStatement s =connection.prepareCall("{ ? = ... }");// Verbose manipulation of statement state: s.registerOutParameter(1, cursor); s.setString(2, "abc"); s.execute(); ResultSet rs = s.getObject(1);// Verbose manipulation of result set state: rs.next(); rs.next();

這些使JDBC成為難以處理的API。 每個對象都是難以置信的有狀態且難以操縱。 具體來說,有兩個主要問題:

  • 在多線程環境中正確處理有狀態的API非常困難
  • 由于沒有記錄狀態,因此很難使全局狀態資源可用

阿甘正傳的戲劇海報,版權所有?1994, 派拉蒙影業 。 版權所有。 可以相信上述用法滿足了所謂的合理使用

規則 :實施更多的功能樣式。 通過方法參數傳遞狀態。 操縱較少的對象狀態。

8.短路equals()

這是一個低落的果實。 在大型對象圖中,如果所有對象的equals()方法首先便宜地比較身份,則可以顯著提高性能:

@Override public boolean equals(Object other) {if (this == other) return true;// Rest of equality logic... }

請注意,其他短路檢查可能還涉及空檢查,該檢查也應該存在:

@Override public boolean equals(Object other) {if (this == other) return true;if (other == null) return false;// Rest of equality logic... }

規則 :短路所有equals()方法以獲得性能。

9.嘗試使方法默認為final

有些人對此持不同意見,因為默認情況下使事情最終完成與Java開發人員所習慣的相反。 但是,如果您完全控制所有源代碼,則默認情況下將方法設為final絕對沒有問題,因為:

  • 如果確實需要重寫方法(確實嗎?),仍然可以刪除final關鍵字
  • 您再也不會意外覆蓋任何方法

這特別適用于靜態方法,在這些方法中,“覆蓋”(實際上是陰影)幾乎沒有任何意義。 最近,我在Apache Tika中遇到了一個非常糟糕的陰影靜態方法示例。 考慮:

  • TaggedInputStream.get(InputStream)
  • TikaInputStream.get(InputStream)

TikaInputStream擴展了TaggedInputStream并使用完全不同的實現來隱藏其靜態get()方法。

與常規方法不同,靜態方法不會互相覆蓋,因為調用站點在編譯時會綁定靜態方法調用。 如果您不走運,您可能會偶然得到錯誤的方法。

規則 :如果您完全控制自己的API,請嘗試在默認情況下盡可能多地使用final方法。

10.避免方法(T…)簽名

偶爾接受一個Object...參數的“ accept-all” varargs方法沒有任何問題:

void acceptAll(Object... all);

編寫這樣的方法給Java生態系統帶來一點JavaScript的感覺。 當然,您可能希望將實際類型限制為在實際情況下更受限的類型,例如String... 而且由于您不想限制太多,您可能會認為用通用T代替Object是一個好主意:

void acceptAll(T... all);

但事實并非如此。 T總是可以推斷為Object。 實際上,您最好不要將泛型與上述方法一起使用。 更重要的是,您可能認為可以重載上述方法,但是您不能:

void acceptAll(T... all); void acceptAll(String message, T... all);

看起來您可以選擇將String消息傳遞給該方法。 但是這里的電話怎么辦?

acceptAll("Message", 123, "abc");

編譯器會推斷<? extends Serializable & Comparable<?>> 為T <? extends Serializable & Comparable<?>> ,這使調用變得模棱兩可!

因此,每當您擁有“所有人都接受”的簽名(即使它是通用的)時,您將永遠無法再次安全地重載它。 API使用者可能只是幸運地“偶然地”選擇了編譯器選擇“正確的”最具體的方法。 但是他們也可能被欺騙使用“ accept-all”方法,或者根本無法調用任何方法。

規則 :如果可以,請避免“全部接受”簽名。 如果不能,則不要重載這種方法。

結論

Java是野獸。 與其他更高級的語言不同,它已經發展到今天。 那可能是一件好事,因為在Java的發展速度下,已經有數百項警告,這些警告只能通過多年的經驗來掌握。

參考:在JAVA,SQL和JOOQ博客上,來自我們JCG合作伙伴 Lukas Eder的Java編碼Java時的10個最佳最佳實踐 。

翻譯自: https://www.javacodegeeks.com/2013/08/10-subtle-best-practices-when-coding-java.html

java微妙

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的java微妙_编码Java时的10个微妙的最佳实践的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人性做爰片免费视频 | 国产69xx| 亚洲一区欧美激情 | 国产精品999 | 中国无码人妻丰满熟妇啪啪软件 | 自拍视频啪 | 色婷婷综合久久久久中文一区二区 | 不卡av电影在线 | 老鸭窝视频在线观看 | 在线视频观看国产 | 狼人精品一区二区三区在线 | 噼里啪啦免费高清看 | 爱操在线| 8050午夜二级 | 国产精品男女视频 | 欧美性生交xxxxx久久久 | 亚洲无吗在线 | 久久久免费精品视频 | 制服丝袜手机在线 | 啦啦啦视频在线观看 | 欧美人妖xxxx | 久久亚洲AV成人无码国产野外 | 欧美污视频在线观看 | 人人射av| juliaannxxxxx高清| 国产奶头好大揉着好爽视频 | 欧美精品一二三四区 | 日韩黄色视屏 | 538国产精品一区二区免费视频 | 久久女同互慰一区二区三区 | 一级片视频网站 | 亚洲国产精品区 | 波多野结衣激情视频 | 男人的天堂免费视频 | 成人1区 | 亚洲精品 日韩无码 | 天天色棕合合合合合合合 | 美女网站免费黄 | 大帝av | 欧美高清性 | 精品自拍第一页 | 美女丝袜av| 波多野结衣一区二区三区中文字幕 | 欧洲影院| 久久在线播放 | 中文字幕亚洲精品在线 | xxxx亚洲| 中国无码人妻丰满熟妇啪啪软件 | 性生活视频在线播放 | 夜夜嗨av禁果av粉嫩av懂色av | 婷婷色综合网 | 午夜啪啪网 | 伊人影院在线观看 | 国产精品成人久久久 | 婷婷激情综合 | 四级黄色片 | 91视色| 黄视频在线免费看 | 天堂中文在线最新 | 国产亚洲在线 | 人妻一区二区三区视频 | 国产一区亚洲 | 亚洲婷婷网 | www.xxx.国产 | 性欧美ⅹxxxx极品护士 | 久久金品 | 在线不卡免费视频 | 日日网站 | 伊人网色 | 一级片大全 | 能直接看的av网站 | 午夜亚洲天堂 | 国模小黎自慰gogo人体 | 无码少妇一区二区三区 | mm131丰满少妇人体欣赏图 | 杏导航aⅴ福利网站 | 粗大的内捧猛烈进出在线视频 | 国产a久久 | 美女在线不卡 | 亚洲中文字幕无码爆乳av | 大陆一级黄色片 | 成人av电影天堂 | 无码成人一区二区 | 色天堂影院| 国产一区欧美日韩 | 亚洲AV无码国产成人久久 | 免费观看黄一级视频 | 久草蜜桃| 日韩精品一区在线视频 | 人人干人人做 | 亚洲九九爱 | 在线视频毛片 | 国产香蕉在线观看 | 天天爽网站 | 国产精品36p | 欧美变态绿帽cuckold | av2018| 奇米激情 | 亚洲成人高清 |