重溫“ Java Sucks”

總覽

關于Java的不足之處(從C開發人員的角度來看)的一個有趣的文檔是在一段時間(大約2000年前)寫的,但是今天許多論點都像十年前一樣真實(或不真實)。
原始的Java Sucks發布。

短消息回顧

Java沒有free()。
作者將其列為受益,并且有99%的時間是勝利。 有時候,當您希望進行逃避分析時,沒有不利之處 會立即消除,回收或釋放您不再需要的對象(恕我直言,JIT / javac應該能夠在理論上解決該問題)

詞法范圍的局部函數
最接近的Java是匿名方法。 對于Closures(Java 8中引入)來說,這是一個差的表親,但是可以使它做同樣的事情。

沒有宏系統
您可以使用宏執行許多有用的技巧,Java可以動態地為您執行。 不需要宏系統是一種資產,因為您不需要知道Java何時會為您提供相同的優化。 宏沒有應用程序啟動成本,并且您無法做真正混淆的事情,但這可能是一件好事。

顯式內聯函數
JIT可以為您內聯方法。 Java可以從共享庫內聯方法,即使它們是動態更新的。 這確實需要花費運行時間,但是更好的是不必擔心此恕我直言。

我發現缺少函數指針是一個巨大的痛苦
函數指針使襯里方法對于編譯器更加困難。 如果您使用的是面向對象的編程,那么我認為您不需要這些。 對于其他情況,我相信Java 8中的Closure可能會更好。

靜態方法不是真正的類方法的事實是相當愚蠢的
我想大多數Java開發人員都會在某個階段遇到此問題。 恕我直言:最好的解決方案是將“靜態”功能移至其自己的類,并且如果需要多態性則不使用靜態方法。

人們如何暗示應該內聯一個方法,否則很快就會真正實現,這遠非顯而易見。
縮小并多次調用。 ;)

兩個相同的byte []數組不相等且不散列相同
我同意它的丑陋設計選擇不使數組成為合適的對象。 它們繼承自Object,但沒有toString,equals,hashCode,compareTo的有用實現。 clone()和getClass()是最有用的方法。 您可以改用輔助方法,但是在不同的程序包中有許多不同的輔助類,分別稱為Array,Arrays,ArrayUtil,ArrayUtils,這對于新開發人員來說是一團糟。

Hashtable / HashMap確實允許您提供哈希函數
如果您想更改行為,這也是一種痛苦。 恕我直言,最好的解決方案是編寫一個實現equals / hashCode的包裝器類,但這會增加開銷。

迭代字符串中的字符,而不隱式涉及每個字符的六個方法調用
現在有String.toCharArray(),但這會創建您不需要的副本,并且不會被轉義分析消除。 如果是這樣,這是顯而易見的解決方案。 同樣的道理也適用于“另一種選擇是先將String轉換為byte [],然后迭代字節,以創建大量隨機垃圾為代價”

在我確定沒有非ASCII字符的情況下,Unicode支持會增加開銷
Java 6為此提供了-XX:+ UseCompressedStrings解決方案。 不幸的是,Java 7放棄了對該功能的支持。 我不知道為什么要在我做的測試中使用此選項來提高性能(以及減少內存使用)。

接口似乎是一個龐大而俗氣的銅版畫,可避免多重繼承。 他們似乎真的是事后被嫁接了。
我更喜歡只列出所提供功能而不添加實現的合同。 Java 8中更新的虛擬擴展方法將提供無狀態的默認實現。 在某些情況下,這將非常有用。

類型提升有些麻煩
Java 5.0+現在支持的協變量返回類型解決了這里的問題。

您不能編寫一個期望和對象的函數并給它一個簡短的描述
今天,您可以進行自動裝箱。 作者抱怨說Short和short不是一回事。 出于效率目的,在某些情況下,使用自動裝箱可能幾乎沒有什么區別。 在某些情況下,它確實有很大的不同,而且我不認為Java在不久的將來會對此進行透明地優化。 :|

如果不知道數組內容的詳細信息,就無法遍歷數組的內容,這是一種總的痛苦。
很少有您真正需要執行此恕我直言。 您可以使用Array.getLength(array)Array.get(array,n)處理通用數組。 它很丑,但是你可以做到。 它是輔助類之一,它實際上應該是數組本身的方法恕我直言。

處理溢出的唯一方法是使用BigInteger(并重寫代碼)
諸如Scala之類的語言支持BigInteger的運算符,并且有人建議Java也應如此。 我相信Java 8/9也將考慮溢出檢測。

我想念typedef
這使您可以使用基元并仍然獲得類型安全性。 恕我直言,真正的問題是JIT無法檢測到類型僅僅是原語(或兩個)的包裝,并且不需要包裝的類。 這將提供typedef的優點,而無需更改語法,并使代碼更面向對象。

我認為用于模擬枚舉和:keywords的可用習語相當la腳
Java 5.0+具有枚舉 ,它們是一流的對象,并且功能強大。

沒有有效的方法來實現“斷言”
assert現在已內置。JIT可以自己實現它。 (大概不是十年前)

通過使“新”成為分配的唯一可能接口,……就有了一整類古老的,眾所周知的優化,人們根本無法執行。
這應該由JIT IMHO執行。 不幸的是,它很少這樣做,但是這種情況正在改善。

敲定系統很la腳。
大多數人都認為最好避免。 也許它可能更強大,更可靠。 答案可能是ARM(自動資源管理)。

相關地,沒有“弱指針”。
Java一直都有弱,軟和幻像引用,但是我懷疑這不是這里的意思。 ??

除了內部變量中的最終變量,您什么都不能關閉!
匿名內部類是正確的,但引用字段的嵌套內部類則沒有。 封閉可能沒有此限制,但可能同樣令人困惑。 由于習慣了最終變量的要求,我尤其沒有發現這個問題。 因為我的IDE會根據我的要求更正代碼。

關于對象的可變性(或只讀性)的訪問模型受到打擊
主要的抱怨似乎是有一些方法可以將最終字段視為可變的。 這是反序列化和依賴注入程序所必需的。 只要您意識到自己有兩個可能的行為,一個級別比另一個級別低,它就會比問題更有用。

該語言還應規定字面常量是不變的。
文字常量是不可變的。 看來作者想擴展什么是文字常量。 恕我直言,以C ++的方式支持const很有用。 const是Java中的關鍵字,而無需創建多個實現或只讀包裝器來定義類的不可變版本的功能將更有效率。

鎖定模型已損壞。
鎖定問題的內存開銷實際上是一個實現細節。 由JVM決定標頭的大小以及是否可以鎖定標頭。 另一個問題是無法控制誰可以獲取鎖。 解決此問題的常用方法是封裝您的鎖,這是您在任何情況下都必須要做的。 從理論上講,鎖可以被優化掉。 當前,只有在優化整個對象時才會發生這種情況。

沒有拋出就沒有信號
為此,我將偵聽器模式與onError方法一起使用。 語言對此沒有支持,但我認為沒有必要。

應該將foo.x定義為等同于foo.x(),
也許foo.x => foo.getX()會是更好的選擇,就像C#一樣。

編譯器應該能夠輕松地內聯零參數訪問器方法,以內聯對象+偏移量加載。

JIT這樣做,而不是編譯器。 這樣就可以在編譯被調用方之后更改調用代碼。

方法“屬于”類的概念是la腳的。
這是某些語言支持的“酷”功能。 在更動態的環境中,這看起來更好。 不利的一面是,您可以在整個地方為某個類編寫一段代碼,并且您將不得不采用某種方式來管理不同庫中的重復項。 例如,庫A定義了一個新的printString()方法,庫B也為同一類定義了一個printString方法。 您將需要使每個庫看到其自己的副本,并具有某種方法來確定C調用此方法時需要哪個版本的庫。

圖書館

它帶有哈希表,但沒有qsort
它帶有一個“優化的合并排序”,旨在加快速度。

字符串的長度為+ byte []的開銷+24個字節
也就是說,無需考慮兩個對象中的每個對象都與8字節邊界對齊(使其更高)。 如果聽起來很糟糕,請考慮將malloc對齊16字節,最小大小為32字節。 如果將shared_ptr用作byte [](以提供類似的資源管理),則在C ++中,它可能比Java大得多。

造成這種開銷的唯一原因是String.substring()可以返回共享相同值數組的字符串。

這是不正確的。 問題是Java不支持可變大小的對象(數組除外)。 這意味著String對象是固定大小的,要擁有可變大小的字段,您必須擁有另一個對象。 無論哪種方式都不是很好。 ;)

String.substring可能是“內存泄漏”的來源
您必須知道要對您進行顯式復制,才能保留較大字符串的子字符串。 這很丑陋,但是好處通常超過了缺點。 更好的解決方案是能夠優化代碼,以便默認情況下采用防御性副本,除非不需要防御性副本(已將其優化掉)

文件操作原語不足
Java 7中改進了文件系統信息。我認為這些選項不可用,但是如果您需要知道這些選項,則可以很容易地推斷出它們。

這不是問“我在Windows上運行”還是“我在Unix上運行”的可靠方法。
系統屬性os.name,os.arch,os.version一直存在。

在Unix上無法訪問link(),這是實現文件鎖定的唯一可靠方法。
這是在Java 7 創建硬鏈接中添加的

除了復制并重命名整個文件外,沒有其他方法可以執行ftruncate()。
您可以使用RandomAccessFile.truncate()。 在Java 1.4中添加。

“%10s%03d”真的有太多要求嗎?
它是在Java 5.0中添加的

RandomAccessFile不能用作FileInputStream或FileOutputStreamRandomAccessFile

支持DataInput和DataOutput,FileInputStream和FileOutputStream可以包裝在DataInputStream和DataOutputStream中。 可以使它們支持相同的接口。 我從未遇到過要在單個方法中同時使用兩個類的情況。

markSupported是愚蠢的
真正。 有許多愚蠢的方法只是出于歷史目的。 另一個是在每個對象(甚至數組)上的Object.wait(millis,nanos ),但是nanos從未真正使用過。

世界和系統運行時之間有什么區別?
我同意這似乎是任意的,在某些情況下會增加一倍。 System.gc()實際上調用Runtime.getRuntime()。gc(),但即使在內部代碼中也被稱為System GC。 在后站點中,它們實際上應該是一類,并將監視功能移至JMX。

世界上是在基礎語言類庫中進行的像checkPrintJobAccess()這樣的應用程序級廢話
因此,您的SecurityManager可以控制是否可以執行打印。 (也不必具有應用程序級安全性管理器)不確定是否確實阻止了對應用程序級安全性的需求。 ;)

參考:在Java Java博客上,我們的JCG合作伙伴 Peter Lawrey 重新審視了“ Java Sucks” 。


翻譯自: https://www.javacodegeeks.com/2012/01/java-sucks-revisited.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373806.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373806.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373806.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android Studio IDE Out of Memory

場景: 嘗試過各種方式,IDE重裝,重新啟動,設置IDE MEMORY大小JDK MEMORY大小都無效 終于在FILE->INVALIDATE CACHES/RESTART 中點擊重新啟動之后問題攻克了。轉載于:https://www.cnblogs.com/yxwkf/p/5128094.html

git 忽略 部分文件夾_git設置忽略文件和目錄

1.登錄gitbash命令端進入本地git庫目錄AdministratorPC201601200946 MINGW32 /d/gitrespository/crmweb (master)2.創建.gitignore3.修改文件,添加忽略正則.idea //忽略.idea文件夾及文件夾下文件*.iml //忽略以.iml結尾的文件【例子】# 忽略*.o和*.a文件*.[oa]# 忽…

在Spring MVC REST應用程序中自動生成WADL

上一次我們學習了WADL的基礎知識 。 語言本身并沒有那么有趣,只寫了一篇有關它的文章,但是本文的標題揭示了為什么我們需要這些知識。 JSR 311的許多實現:JAX-RS:RESTful Web服務的Java API提供了開箱即用的運行時WADL生成&#x…

JSP靜態導入與動態導入

JSP靜態導入(JSP指令標記include) JSP頁面第一次被請求時,會被JSP引擎轉譯成Servlet的Java文件,然后再被編譯成字節碼文件執行。JSP指令標記為JSP頁面轉譯提供整個頁面的相關信息。 include指令用于在JSP頁面靜態插入一個文件&…

關于DJANGO和JAVASCRIPT的時間

最近,實際一些簡單統計時,要到庫里去檢索數據出來用HIGHCHARTS畫圖, 作一個簡單的回照。。 DJANGO用TEMPLATEVIEW來作。專業,正規:) class SAView(TemplateView):template_name version/sa_site.htmlpagin…

git里面的文件怎么刪不掉_.git目錄刪不掉

這樣的情況并非是第一次遇到了,以前總是會覺得這樣的問題只是電腦的錯亂,重啟一下電腦就好了,但是并非每次都需要重啟電腦的,其實簡單的設置一下,這個問題就可以解決了。對了,咱們還是說說這到底是個什么問…

集成框架比較– Spring集成,Mule ESB或Apache Camel

公司之間的數據交換增加了很多。 必須集成的應用程序數量也增加了。 這些接口使用不同的技術,協議和數據格式。 但是,這些應用程序的集成應以標準化的方式建模,有效實現并由自動測試支持 。 JVM環境中提供了三個可滿足這些要求的集成框架&…

Vue.js組件學習

組件可以擴展HTML元素&#xff0c;封裝可重用的HTML代碼&#xff0c;我們可以將組件看作自定義的HTML元素。組件系統提供了一種抽象&#xff0c;讓我們可以使用獨立可復用的小組件來構建大型應用。 一個簡單組件例子(全局注冊&#xff09; <!DOCTYPE html> <html>&…

Winform MD5

1&#xff1a;MD5 http://www.cmd5.com/ 字節數組----字符串 //將字節數組中每個元素按照指定的編碼格式解析成字符串//直接將數組ToString()//將字節數組中的每個元素ToString() //ToString("Params") ToString("x") //可以將十進制字符串轉換為16進制字符…

HTML元素顯示與隱藏

在WEB開發中&#xff0c;前臺HTML中經常需要控制元素的隱藏與顯示&#xff0c;我們最為最常見是二級導航欄&#xff08;通過鼠標的移動來觸發onmouseover&#xff0c;onmouseout事件來實現二級菜單的顯示與隱藏&#xff09;二級菜單的顯示與隱藏。 然而控制元素的影響與顯示有…

書評:JavaFX 2.0:示例介紹

盡管Oracle在JavaOne 2010和JavaOne 2011上對JavaFX的更改使我從懷疑論者轉變為對JavaFX的信奉者 &#xff0c;但是JavaFX愿景的轉變并非沒有缺點 。 特別是&#xff0c;JavaFX圖書市場一直很棘手&#xff0c;因為幾乎所有可用的JavaFX圖書都與1.x版本有關。 在這篇文章中&…

腦子越來越不好使,文字越來越像馱shi

沒辦法&#xff0c;還是記下來。。。轉載于:https://www.cnblogs.com/thorlet/p/5926595.html

python機制_python異常機制個人理解(參考網上資料)

當你的程序中出現異常情況時就需要異常處理。比如當你打開一個不存在的文件時。當你的程序中有一些無效的語句時&#xff0c;Python會提示你有錯誤存在。下面是一個拼寫錯誤的例子&#xff0c;print寫成了Print。Python是大小寫敏感的&#xff0c;因此Python將引發一個錯誤&…

NYOJ 24 素數距離問題

素數距離問題 時間限制&#xff1a;3000 ms | 內存限制&#xff1a;65535 KB難度&#xff1a;2描述 現在給出你一些數&#xff0c;要求你寫出一個程序&#xff0c;輸出這些整數相鄰最近的素數&#xff0c;并輸出其相距長度。如果左右有等距離長度素數&#xff0c;則輸出左側的…

C#控件大小隨窗體大小等比例變化

相信很多博友在開發初次接觸學習C# winForm時&#xff0c;當窗體大小變化時&#xff0c;窗體內的控件并沒有隨著窗體的變化而變化&#xff0c;最近因為一個項目工程的原因&#xff0c;也需要解決這個問題。通過查閱和學習&#xff0c;這個問題得到了解決&#xff0c;或許不是很…

Google Appengine登臺服務器操作方法

Google的App Engine開箱即用&#xff0c;支持版本化部署。 您可以非常輕松地在各修訂版之間來回切換&#xff0c;這是在上線之前正確測試應用程序的一項很棒的功能。 有一個主要問題&#xff1a;應用程序的所有版本共享同一數據存儲。 因此&#xff0c;如果要遷移數據&#xff…

下 面 這 條 語 句 一 共 創 建 了 多 少 個 對 象 : String s=a+b+c+d;

javac 編譯可以對字符串常量直接相加的表達式進行優化&#xff0c; 不必要等到運行期去進行加法運算處理&#xff0c; 而是在編譯時去掉其中的加號&#xff0c; 直接將其編譯成一個這些常量相連的結果。題目中的第一行代碼被編譯器在編譯時優化后&#xff0c; 相當于直接定義了…

公共樣式_設計干貨 | 園路鋪裝的100種樣式,保存收好

Part 1園路的形式主干道&#xff1a;聯系全園&#xff0c;必須考慮通行、生產、救護、消防、游覽的需要。次干道&#xff1a;溝通各景點、建筑&#xff0c;通輕型車輛。休閑小徑、健康步道&#xff1a;健康步道是近年來最為流行的足底按摩健身方式。通過行走卵石路上按摩足底穴…

22個所見即所得在線 Web 編輯器

新聞來源:sixrevisions.com我們曾介紹過 10 個基于 JavaScript 的 WYSIWYG&#xff08;所見即所得&#xff09; 編輯器&#xff0c;這些 Web 編輯器可以在線編輯和處理富 Web 內容&#xff0c;包括格式文本&#xff0c;表格&#xff0c;圖片&#xff0c;媒體&#xff0c;鏈接等…

配置阿里云作為yum 源

第一步&#xff1a;下載aliyum 的yum源配置文件。 http://mirrors.aliyun.com/repo/ 第二步&#xff1a;把下載到的repo文件復制到/etc/yum.repo.d/目錄下。 ----------------------------------------------------下面是本地yum源的一個例子 [base_extra]namebase & extra…