Java,如果这是一个更好的世界
只是夢(mèng)想著有一個(gè)更好的世界,在該世界中,Java平臺(tái)中的一些舊錯(cuò)誤已得到糾正,而某些令人敬畏的缺失功能也已實(shí)現(xiàn)。 不要誤會(huì)我的意思。 我認(rèn)為Java很棒。 但是它仍然存在一些問題,就像其他平臺(tái)一樣。 我希望沒有這些特定的命令,而不必聲稱自己幾乎是詳盡無遺的,更重要的是,如果沒有要求您經(jīng)過深思熟慮且完全正確,我希望這些事情:
可串行性
在對(duì)象內(nèi),可串行性是默認(rèn)設(shè)置。 如果您不希望成員可序列化,則將其標(biāo)記為“瞬態(tài)”。 為什么在地球上我們必須添加這個(gè)愚蠢的標(biāo)記
接口“可序列化”到我們所有的類?
默認(rèn)情況下,所有對(duì)象都應(yīng)可序列化。 非可銷售性應(yīng)該是明確標(biāo)記的“功能”
當(dāng)然,可序列化性本身具有許多我不會(huì)涉及的奇怪細(xì)節(jié),在這里
克隆
由于默認(rèn)情況下所有對(duì)象都應(yīng)可序列化,
默認(rèn)情況下,所有對(duì)象也應(yīng)該是可克隆的。 不可克隆性應(yīng)該是明確標(biāo)記的“功能”
此外,淺克隆幾乎是無用的。 因此
默認(rèn)情況下,所有對(duì)象都應(yīng)深克隆自己。 淺克隆可以顯式實(shí)現(xiàn)
注意,clone方法應(yīng)該是java.lang.System或某些其他實(shí)用程序中的某些本機(jī)方法。 它不應(yīng)位于java.lang.Object上,從而允許客戶端代碼實(shí)現(xiàn)正確的克隆解釋,而不會(huì)發(fā)生任何偶然的名稱沖突。 或者,可以實(shí)現(xiàn)類似的私有回調(diào)方法,如果應(yīng)定制克隆,則采用與序列化相同的方式。
無符號(hào)數(shù)字
為什么這不是Java的一部分?
所有整數(shù)基元以及java.lang.Number包裝器都應(yīng)該有一個(gè)無符號(hào)版本。
原語
基元是API支持的一種痛苦。 從語法角度來看,int和Integer應(yīng)該相同。 int []和Integer []也應(yīng)該是
應(yīng)將原語及其包裝器更好地集成到語言和JVM中
如果不放棄真正的原語所提供的性能優(yōu)勢(shì),這可能是無法真正解決的。 看到Scala…
物產(chǎn)
Getter和Setter并不是最先進(jìn)的技術(shù)。
應(yīng)該更正式地支持屬性
另請(qǐng)參閱此博客上的最新文章及其評(píng)論: http : //blog.jooq.org/2013/01/12/bloated-javabeans-part-ii-or-dont-add-getters-to-your-api/
館藏
集合API應(yīng)該與該語言更好地集成。 像許多其他語言一樣,應(yīng)該可以使用方括號(hào)和花括號(hào)取消引用集合的內(nèi)容。 JSON語法將是顯而易見的選擇。 應(yīng)該可以這樣寫:
// Translates to new ArrayList<>(...); List<Integer> list = [ 1, 2, 3 ];// Translates to list.get(0); Integer value = list[0];// Translates to list.set(0, 3); list[0] = 3;// Translates to list.add(4); list[] = 4;// Translates to new LinkedHashMap<>(...); Map<String, Integer> map = { 'A': 1, 'B': 2 }; // Translates to map.get(0); Integer value = map['A']// Translates to map.put('C', 3); map['C'] = 3;線程本地
在某些情況下,ThreadLocal可能是一件好事。 ThreadLocal的概念可能不是100%合理的, 因?yàn)樗赡軐?dǎo)致內(nèi)存泄漏 。 但是假設(shè)沒有問題,
threadlocal應(yīng)該是關(guān)鍵字,例如volatile和transient
如果transient值得作為關(guān)鍵字,那么threadlocal也應(yīng)該是。 這將如下工作:
class Foo {threadlocal Integer bar;void baz() {bar = 1; // Corresponds to ThreadLocal.set()Integer baz = bar; // Corresponds to ThreadLocal.get()bar = null; // Corresponds to ThreadLocal.remove()} }當(dāng)然,這樣的關(guān)鍵字也可以應(yīng)用于原語
參考文獻(xiàn)
引用在Java中有些奇怪。 它們?cè)趈ava.lang.ref包中作為Java對(duì)象實(shí)現(xiàn),但是JVM和GC對(duì)其進(jìn)行了特殊處理。
就像threadlocal一樣,應(yīng)該有關(guān)鍵字來表示參考
當(dāng)然,隨著泛型的引入,添加這樣的關(guān)鍵字幾乎沒有收獲。 但是,某些類在JVM中“非常特殊”,但沒有語言語法功能,仍然感到難聞。
反射
請(qǐng)! 為什么在地球上必須如此冗長? 為什么Java(Java語言)不能更加動(dòng)態(tài)? 我不是在要求Smalltalk-一種動(dòng)態(tài)的功能,但是反射不能像語法糖那樣以某種方式內(nèi)置到語言中嗎?
Java語言應(yīng)允許特殊的語法進(jìn)行反射
當(dāng)然,可以在庫級(jí)別上實(shí)現(xiàn)一些緩解。 jOOR就是一個(gè)例子。 還有很多。
介面
Java中的接口總是感覺很奇怪。 具體來說,使用Java 8的擴(kuò)展方法,隨著它們靠近抽象類,它們開始失去生存的權(quán)利。 當(dāng)然,即使使用Java 8,主要區(qū)別也在于類不允許多重繼承。 接口可以–至少,它們?cè)试S規(guī)范(抽象方法)和行為(默認(rèn)方法)的多重繼承,而不是狀態(tài)的繼承。
但是他們?nèi)匀桓械焦之?#xff0c;主要是因?yàn)樗鼈兊恼Z法與類不同,而它們的功能卻在融合。 lambda專家組為何決定引入默認(rèn)關(guān)鍵字? 如果接口允許使用抽象方法(如今天)和具體方法(防御器方法,擴(kuò)展方法),為什么接口的語法不能與類相同? 我沒有運(yùn)氣就問過專家組: http : //mail.openjdk.java.net/pipermail/lambda-dev/2012-August/005393.html 。 不過,我還是希望……
適當(dāng)時(shí),接口語法應(yīng)與類語法完全相同
這包括靜態(tài)方法,最終方法,私有方法,程序包私有方法,受保護(hù)的方法等。
默認(rèn)可見性
默認(rèn)可見性不應(yīng)通過缺少private / protected / public關(guān)鍵字來指定。 首先,在類和接口中無法用相同的方式處理這種缺失。 然后,它不是很可讀。
默認(rèn)可見性應(yīng)通過“包”或“本地”或類似關(guān)鍵字指定
文字
這將是日常工作中的絕佳補(bǔ)充。
應(yīng)該有列表,映射,正則表達(dá)式,元組,記錄,字符串(改進(jìn)),范圍文字
我之前已經(jīng)在此發(fā)布過博客: http : //blog.jooq.org/2012/06/01/array-list-set-map-tuple-record-literals-in-java/ 。 在這里找到了Brian Goetz在lambda-dev郵件列表中提到的一些想法: http : //mail.openjdk.java.net/pipermail/lambda-dev/2012-May/004979.html
#[ 1, 2, 3 ] // Array, list, set #{ 'foo' : 'bar', 'blah' : 'wooga' } // Map literals #/(\d+)$/ // Regex #(a, b) // Tuple #(a: 3, b: 4) // Record #'There are {foo.size()} foos' // String literal我會(huì)加
#(1..10) // Range (producing a List)最后
方法,屬性,參數(shù),局部變量,都可以聲明為“最終”。 在許多方面,不變性是一件好事,應(yīng)予以鼓勵(lì)(我很快會(huì)在博客中介紹)。 其他語言(例如Scala)區(qū)分“ val”和“ var”關(guān)鍵字。 除了那些其他語言令人印象深刻的類型推斷功能之外,在大多數(shù)情況下,val比var更可取。 如果要表達(dá)可修改的變量,他們?nèi)匀豢梢允褂谩?var”
Final應(yīng)該是成員,參數(shù)和局部變量的默認(rèn)行為
覆寫
意外重寫方法很危險(xiǎn)。 其他語言通過在覆蓋上引起編譯錯(cuò)誤來解決此問題
應(yīng)該引入重寫關(guān)鍵字以顯式重寫方法
可以將某些Java編譯器(例如Eclipse編譯器)配置為在缺少java.lang.Override批注時(shí)發(fā)出警告/錯(cuò)誤。 但是,這實(shí)際上應(yīng)該是關(guān)鍵字,而不是注釋。
模組
依賴管理是Java的噩夢(mèng)。 還有另一種語言可以根據(jù)模塊構(gòu)建編譯單元: Fantom 。 Stephen Colebourne(JodaTime的家伙)是Fantom的忠實(shí)粉絲,并在Devoxx上發(fā)表了演講。 他還不時(shí)發(fā)布有關(guān)Fantom的博客: http : //blog.joda.org/search/label/fantom
編譯單元應(yīng)以“模塊” / jar文件的形式表示
當(dāng)然,這會(huì)使Maven過時(shí),因?yàn)镴ava編譯器已經(jīng)可以更好地處理依賴關(guān)系。
變量和泛型
來吧。 @SafeVarargs ?? 當(dāng)然,由于泛型類型擦除,這永遠(yuǎn)無法完全正確解決。 但是還是
不應(yīng)有泛型類型擦除
元組和記錄
我真的認(rèn)為這是Java缺少的東西
元組和記錄應(yīng)該有語言支持
Scala集成了最多22個(gè)元組,.NET支持最多8個(gè)元組。這在Java語言中也是一個(gè)不錯(cuò)的功能。 具體來說,記錄(或結(jié)構(gòu))將是一件很不錯(cuò)的事情。 如前所述,元組和記錄也應(yīng)使用文字。 遵循以下原則:
#(a, b) // Tuple #(a: 3, b: 4) // Record編譯器
遠(yuǎn)遠(yuǎn)超出添加一些注釋處理的編譯器API會(huì)很好。 我很希望能夠擴(kuò)展Java語言本身。 我想將SQL語句直接嵌入Java代碼中,類似于可嵌入PL / SQL中的SQL。 當(dāng)然,此類SQL代碼將由jOOQ之類的庫支持 。
編譯器API應(yīng)該允許任意語言擴(kuò)展
當(dāng)然,這種改進(jìn)的編譯器API應(yīng)該以一種自動(dòng)完成,語法突出顯示和其他功能在Eclipse之類的IDE中自動(dòng)運(yùn)行的方式來完成,因?yàn)榫幾g器擴(kuò)展將能夠向IDE公開必要的工件。 好,我同意,這種改進(jìn)是很多夢(mèng)想
類型推斷
如果沒有歧義,難道類型推斷不能像Scala一樣強(qiáng)大嗎? 我不想寫下每個(gè)局部變量的完整類型。 應(yīng)該支持Scala的本地類型推斷
運(yùn)算符重載
好的,這是一個(gè)高度宗教性的話題。 你們中的許多人不同意。 但是我喜歡
Java應(yīng)該支持運(yùn)算符重載
使用操作符而不是方法可以更好地表達(dá)某些庫操作。 想想BigInteger和BigDecimal的冗長冗長的API。
添加評(píng)論!
當(dāng)然,缺少lambda和擴(kuò)展方法,并且泛型也被刪除。 盡管后者永遠(yuǎn)不會(huì)修復(fù),但是第一個(gè)將在Java 8中運(yùn)行。因此,請(qǐng)?jiān)廠un和Oracle,讓我們等了很長時(shí)間等待lambda。
參考: Java,如果這是我們的JCG合作伙伴 Lukas Eder在JAVA,SQL和JOOQ博客上提出的更好的世界 。
翻譯自: https://www.javacodegeeks.com/2013/02/java-if-this-were-a-better-world.html
總結(jié)
以上是生活随笔為你收集整理的Java,如果这是一个更好的世界的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Google Guava的订购API
- 下一篇: JavaEE概念简介