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

歡迎訪問 生活随笔!

生活随笔

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

java

java循坏_Java的坏功能是什么

發布時間:2023/12/3 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java循坏_Java的坏功能是什么 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

java循壞

總覽

當您第一次學習開發時,您會看到關于不同功能的過分籠統的陳述,它們對于設計,性能,清晰度,可維護性都是不好的,感覺就像是黑客,或者他們只是不喜歡它。

這可能會得到現實世界經驗的支持,在實際經驗中,刪除功能的使用可以改善代碼。 有時這是因為開發人員不知道如何正確使用該功能,或者該功能固有地容易出錯(取決于您是否喜歡它)

當時尚或您的團隊改變并且此功能變得很好甚至是首選方法時,這令人感到不安。

在這篇文章中,我將介紹一些人們討厭的功能,以及為什么我認為使用正確的功能應該是有益的力量。 功能并不像是/否,好/壞,就像許多人相信的那樣。

檢查異常

對于開發人員不喜歡考慮錯誤處理的程度,我經常感到驚訝。 新開發人員甚至不喜歡閱讀錯誤消息。 這是艱苦的工作,他們抱怨應用程序崩潰,“它不起作用”。 他們不知道為什么錯誤消息和堆棧轉儲經常告訴他們如果他們只能看到線索的地方到底出了什么問題,為什么會引發異常。 當我出于跟蹤目的而寫出堆棧跟蹤信息時,許多人只會看到日志沒有錯誤時就像崩潰一樣。 閱讀錯誤消息是一種技巧,起初它可能會讓人不知所措。

同樣,也經常避免以有用的方式處理異常。 我不知道該異常該怎么辦,我寧愿記錄該異常并假裝該異常未發生,或者只是炸掉,然后讓操作人員或GUI用戶處理錯誤的能力最弱。

結果,許多經驗豐富的開發人員都討厭檢查異常。 但是,我聽到的越多,我越高興Java檢查了異常,因為我堅信Java確實會發現忽略異常非常容易,并且只要不被它們煩惱就讓應用程序死亡。

檢查異常當然可以被過度使用。 問題應該是在引發檢查異常時; 我是否想通過迫使他們對錯誤處理進行一點思考來惹惱開發人員調用代碼? 如果答案是肯定的,則拋出一個已檢查的異常。

恕我直言,這是lambda設計的失敗,因為它無法透明地處理檢查的異常。 例如,作為自然代碼塊,可以拋出未處理的異常,就像處理未經檢查的異常和錯誤一樣。 但是,考慮到lambda和函數式編程的歷史,它們根本不喜歡副作用,更不用說快捷錯誤處理了,這也就不足為奇了。

您可以通過重新拋出已檢查的異常(好像它是未檢查的異常)來解決lambda的限制。 之所以可以這樣做是因為JVM沒有檢查異常的概念,它像泛型一樣是編譯時檢查。 我的首選方法是使用Unsafe.rethrowException,但還有3種其他方式可以做到這一點。 盡管Thread.currentThread()。stop(e)總是很安全,但它在Java 8中不再起作用。

Thread.currentThread()。stop(e)不安全嗎?

當方法Thread.stop(Throwable)可能導致另一個線程在代碼的隨機部分觸發異常時,它是不安全的。 這可能是一部分代碼中未檢查到的異常,也可能是拋出該異常的原因,該異常捕獲在線程的某些部分,但其他部分則使您不知所措。

但是,它不安全的主要原因是,它可能會使原子操作處于不一致狀態的代碼鎖定部分的同步狀態,從而以微妙且不可測試的方式破壞內存。
更令人困惑的是,Throwable的堆棧跟蹤與實際引發異常的線程的堆棧跟蹤不匹配。

但是Thread.currentThread()。stop(e)呢? 這將觸發當前線程在當前行上引發異常。 這并不比僅使用throw異常執行正在執行的編譯器無法檢查的操作更糟。 問題是編譯器并不總是知道您在做什么,以及它是否真的安全。 對于仿制藥,這被歸類為“未經檢查的演員表”,這是一個警告,您可以通過注釋將其禁用。 Java不能很好地支持帶有已檢查異常的同類操作,您最終會使用hack,或者更糟的是將真正的已檢查異常隱藏為運行時異常,這意味著調用者無法正確處理它。

使用

對我來說,這是一個新的“規則”。 我知道它來自哪里,但是該規則比應該應用的地方有更多例外。 讓我們首先考慮所有可以使用重載static的上下文。

  • 靜態可變字段
  • 靜態不可變字段(指向不變的對象的最終原始或最終字段)
  • 靜態方法。
  • 靜態類(沒有隱式引用外部實例)
  • 靜態初始化程序塊。
  • 我同意使用靜態可變字段很可能是新手錯誤,還是有可能避免的事情。 如果您看到靜態字段在構造函數中被更改,則幾乎可以肯定是一個錯誤(即使沒有,我也會避免),我相信這是避免所有靜態語句的原因。

    但是,在所有其他情況下,使用static不僅性能更高,而且更清楚。 它顯示此字段對于每個實例都不同,或者該方法或類并不隱式依賴于實例。

    簡而言之,static是好的,可變的static字段是例外,而不是規則。

    Singletons不好嗎?

    單例的問題來自兩個方向。 它們是有效的全局可變狀態,使其難以維護或封裝(例如在單元測試中),并且支持自動接線。 也就是說,任何組件都可以訪問它,從而使您的依賴項變得不清楚并且難以管理。 由于這些原因,一些開發人員討厭它們。

    但是,遵循良好的依賴關系注入是一種應該應用于所有組件(無論是否單例)的方法,并且應該避免通過單例避免全局可變狀態。

    如果排除全局狀態和自連接組件,則剩下的Singleton是不可變的,并通過依賴注入傳遞,在這種情況下,它們可以正常工作。 我用于實現策略的一種常見模式是將枚舉與一個實現接口的實例一起使用。

    enum MyComparator implements Comparator {INSTANCE;public int compare(MyObject o1, MyObject o2) {// something a bit too complicated to put in a lambda}}

    該實例可以通過依賴項注入作為Comparator的實現傳遞,并且沒有可變狀態,可以在線程和單元測試之間安全地使用它。

    我可以讓一個庫或框架為我做一件非常簡單的事情嗎?

    庫和框架可以為您節省大量時間和精力,使您自己的代碼執行在其他地方已經可以使用的操作。

    即使您想編寫自己的代碼,我也強烈建議您了解現有庫和框架的功能,以便從中學習。 自己編寫它不是避免理解任何現有解決方案的捷徑。 一位記者曾經絕望地寫到一位有抱負的記者。 不喜歡讀書,只喜歡寫作。 在軟件開發中也是如此。

    但是,我已經看到(在Stackoverflow上)開發人員竭盡全力避免將自己的代碼用于瑣碎的示例。 他們覺得如果使用庫,它必須比他們編寫的任何東西都要好。 問題在于它是假定的。 添加庫不會增加復雜性,您對庫有很好的了解,而且您將不需要學習編寫可以信任的代碼。

    一些開發人員使用框架來幫助學習實際上是一種方法論。 實際上,開發人員通常會使用純Java進行依賴注入的框架,但是他們要么不信任自己,要么不信任自己的團隊來這樣做。

    在高性能空間中,代碼越簡單,應用程序所做的工作就越少,使用更少的活動部件進行維護就越容易,并且運行速度也就越快。 您需要使用最少的庫和框架,這些庫和框架應相當容易理解,以便使系統發揮最佳性能。

    用雙倍賺錢不好嗎?

    使用小數而不考慮舍入會給您帶來意想不到的結果。 從正面看,對于雙精度數,通常顯然是錯誤的,例如10.99999999999998,而不是11。

    有些人認為BigDecimal是解決方案。 但是,問題在于BigDecimal具有自己的陷阱,很難進行驗證/讀取/寫入,但是如果沒有,最糟糕的情況是看起來正確。 舉個例子:

    double d = 1.0 / 3 * 3 + 0.01;BigDecimal bd1 = BigDecimal.valueOf(1.0).divide(BigDecimal.valueOf(3), 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(3)).add(BigDecimal.valueOf(0.01)).setScale(2, BigDecimal.ROUND_HALF_UP);BigDecimal bd2 = BigDecimal.valueOf(1.0).divide(BigDecimal.valueOf(3), 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(3).add(BigDecimal.valueOf(0.01))).setScale(2, BigDecimal.ROUND_HALF_UP);System.out.println("d: " + d);System.out.println("bd1: " + bd1);System.out.println("bd2: " + bd2);

    這將產生三個不同的結果。 通過觀察,哪一個產生正確的結果? 您能說出bd1和bd2之間的區別嗎?

    打印:

    d: 1.01 bd1: 1.00 bd2: 0.99

    您可以從輸出中看到哪個錯誤嗎? 實際上答案應該是1.01。

    BigDecimal的另一個難題是equals和compareTo的行為不同。 當compareTo()返回0時,equals()可以為false。即,在BigDecimal 1.0中,等于1.00時為false,因為比例不同。

    BigDecimal的問題在于,您獲得的代碼通常更難于理解,并且會產生看起來不正確的錯誤結果。 BigDecimal的速度明顯較慢,并且會產生大量垃圾。 (這在Java 8的每個版本中都在改進)在某些情況下,BigDecimal是最佳解決方案,但并非如某些人所反對的那樣。

    如果BigDecimal不是一個很好的選擇,還有其他嗎? int和long通常以固定的精度使用,例如,整數而不是分數。 這有一些挑戰,您必須記住小數位在哪里。 如果Java支持值類型,將它們用作金錢包裝器并為您提供更多安全性可能是有意義的,但是處理整數基元的控制,說明和性能可能會有所提高。

    使用

    對于NullPointerException Java的開發人員而言,重復獲得NullPointerException是一種消耗體力的經歷。 我真的必須為Java中數組中的每個對象,每個元素創建一個新實例嗎? 其他語言則不需要這樣做,因為通常是通過嵌入式數據結構來完成的。 (某些正在考慮用于Java的東西)

    即使是經驗豐富的Java開發人員也難以處理null值,并且將這種語言的null視為一個大錯誤。 恕我直言,問題在于替代品通常更差。 例如不是NPE的NULL對象,但也許應該已經初始化為其他對象。 在Java 8中,Optional是一個很好的添加,它使對非結果的處理更加清晰。 我認為這對于那些與NullPointerException斗爭的人很有用,因為它迫使您考慮可能根本沒有結果。 這不能解決未初始化字段的問題。

    我個人不喜歡它,因為它解決了一個問題,可以通過正確處理null來更廣泛地解決問題,但是我知道對于許多人來說,這是一種改進。

    一個常見的問題是; 我應該如何知道變量為空? 這是我心中錯誤的方法。 應該是,為什么要假設它不能為null? 如果您不能回答該問題,則必須假定它可以為null,并且如果不進行檢查,NPE也就不會感到驚訝。

    您可能會爭辯說Java可以使用更多的語法糖來制作處理Elvis運算符之類的null清除程序的代碼,但我認為問題在于開發人員沒有充分考慮null值。 例如,您是否在打開枚舉變量之前檢查它是否為null? (我認為應該有一個case null的case null :在switch中,但不存在或陷入default :但事實并非如此)

    快速編寫代碼有多重要?

    Java不是一種簡潔的語言,沒有IDE可以為您編寫一半的代碼,如果您花了一整天時間編寫代碼,那么編寫esp將會非常痛苦。

    但這就是開發人員整日不做的事情嗎? 實際上,他們沒有。 開發人員不會花費很多時間來編寫代碼,他們會花費90%(用于新代碼)到99%(用于遺留代碼)來理解問題 。

    你可能會說; 我一整天以后寫一千行代碼,然后重新編寫代碼(通常使其更短),一段時間后我修復了代碼。但是,盡管您仍然想起這段代碼,但是如果您只是編寫最后需要的代碼(或從打印輸出中完成),然后將其除以在項目上花費的總時間,從頭到尾,您可能會發現實際上每天少于100行代碼,每天可能少于10行。

    所以,如果那段時間不是寫最終產品,那您實際上在做什么? 據了解,最終用戶需要什么,以及實施該解決方案需要什么。

    曾經有人告訴我; 如果您在錯誤的位置鉆Kong,則無論鉆Kong多快,多大,有多深或有多少個Kong都無所謂。

    結論

    我聽到了從初學者到杰出開發人員的觀點,聲稱您不應該/我無法想象為什么/如果您使用X,您應該被解雇,應該只使用Y。我發現這樣的陳述很少是100%準確的。 通常,要么存在極端情況,有時在非常常見的情況下,這種陳述具有誤導性或完全不正確。

    我會持懷疑態度來對待任何這樣的廣泛評論,而且他們常常發現一旦發現其他人沒有相同的看法,他們就必須限定所說的內容。

    翻譯自: https://www.javacodegeeks.com/2015/05/what-are-the-bad-features-of-java.html

    java循壞

    總結

    以上是生活随笔為你收集整理的java循坏_Java的坏功能是什么的全部內容,希望文章能夠幫你解決所遇到的問題。

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