希望 Java 未來能新增的特性

更新於 2024/04/26閱讀時間約 9 分鐘
此為過去的舊文,2014 年 4 月 26 日初次發表於 logdown。

今天來點輕鬆的,這應該算是看完《超越 Java -- 探討程式語言的未來》多年後最近再次思考的一些心得:近幾年 Java 太重視 Library (J2EE 已經變成龐然大物)了,忽略了語言本身的問題(J2SE 7 的 auto-closable resource in try-catch 和 J2SE 8 的 Lambda 恐怕是繼 J2SE 5 的 Generic/Autoboxing 後針對語言本身所做的少數改變)。

Java SE 8 已經發布,甚至短短一個月不到(2014/3/18 -> 2014/4/15),就發布的 Java SE 8 Update 5 (從Oracle接手後,版本號碼跳超快的),下一個版本 Java SE 9 似乎已經開始蠢蠢欲動,不過在接觸幾種不同語言後,其實有幾個語言特性 (不一定是功能),我到蠻希望 Java 能加入的。

第一個我希望加入的是 Property,其實蠻多語言都有類似的語言特性,例如 Objective C 和 C# 都有,property 可以像存取變數值那樣使用,例如 for(Publication* publication in person.publications) 取得著作,或是 page.Height = 400 指定頁面高度,但它和直接把成員變數宣告成 public 不同,因為 property 還是有存取權限的設定,由不同存取權限的 getter 和 setter 所組成的,所以在範例中,改變高度是會通知 handlers (observer pattern) 的。只是多數語言有提供預設實作,或是提供機制自動產生,例如 @synthesize firstName;。雖然 Java 可以使用 Lombok 動生成 getter/setter,但終究不是語言的一部分,而且我討厭用 annotation 做這件事(好吧!關於 annotation 純屬我個人喜好問題)。


第二個特性是 Literal data structure declaration,JavaScript 和 Objective C 等語言都有提供類似的特性。有時候在處理資料時,只是想要個簡單的資料物件 (data object),但就是一定要寫個 class,然後提供 getter/setter 的實作,這實在太麻煩了,如下所示,馬上就能組出一個 company 資料物件,沒錯,Objective C 從 JavaScript Object Notation (JSON) 那裡參考來的,只是要加上小老鼠 @ 作為識別。Java 也許該考慮一下!小抱怨一下,為什麼內建的 JSON API 只有在 J2EE 中才有,難道 client 不需要解析 JSON 嗎?真是奇怪的一件事。


第三個希望新增到Java中的特性是 Category,這是我在學 Objective C 後很喜歡的一個語言特性,category 是一種可以用來黏合新實作到既有物件的方式,但又不是繼承,因為型別沒有改變,也不是 C# 的 partial keyword。這在設計複雜的專案時很方便,可以依據功能分類到不同的檔案中,而且可以依據需求只使用部分的功能。例如:POJO (Plain Old Java Object) 物件與 JSON 之間的轉換,到底應該算是物件本身自己該做的事?還是由別的物件負責做轉換?

我剛開始學 OO 語言時,會覺得是前者,但後來多看了很多設計後,我傾向後者,畢竟物件可輸出成多種格式 (JSON或XML),想要新增一種輸出格式時,得修改原物件有點違反 open close principle,而且在沒有原始碼的情況下,修改原物件也不可能,只能用繼承,但繼承又會改變型態。但如果有 category 機制,就可以將新格式輸出的實作黏合到既有物件中。

例如,Person 物件在原本的 Person.h 中只需要提供 domain model 所需的邏輯即可,而 JSON 相關的邏輯實作則是放在 JSON 的 category 中,若需要 JSON 相關的邏輯實作,才需要匯入 (import) Person+JSON.h,若不需要,只需匯入一般的 Person.h 即可,這時 JSON 相關的實作也看不到。而且在沒有原始碼的情況下也可以用 category 來黏合新實作,我就常用 category 替 NSString 加新東西。


第四個特性是 Extension,這也是 Objective C 的一個語言特性。我希望加入 Java 中是和測試有關,Objective C 雖然有 @public@protected@private 關鍵字,但是用在成員變數上,而不是函式上。Objective C 沒有要求函式一定要宣告在 .h 檔中,所以大多數情況下是把不希望被知道的函式直接寫在 .m 檔中,有時候為了測試方便會希望,某些原本宣告成private的函式能在測試期間暫時變成 public。

這時 extension 就派上用場了,如下所示,將希望公開的函式放在 Person.h 檔中,不希望公開但希望在測試期間被看到的 private 函式則放 Person_Private.h 中,公開程式時只公開 Person.h 檔,Person_Private.h 檔則不公開,測試時匯入 Person_Private.h 檔就能看到想測的 private 函式 (其實,Objective C 的 extension 還可以更狠,連 extension 的 .h 檔都不需要,直接在測試程式中,強制把 private methods 變成公開的 XD)。雖然 Java 沒有 .h 標頭檔和 .m 實作檔分離的設計,但如果能有 private interface implementation 的話,也許可以提供類似的特性。


第五個特性是與 IDE 整合用的 Preprocessor。雖然有不少人因為 IDE 越來越笨重開始回歸單純,使用一般 (說一般也不對,因為還是有 syntax highlighted 等功能) 的文字編輯器寫程式,但我想還是有不少人是用 IDE 在寫程式 (我也一度覺得Eclipse超慢的,在想找替代品時發現 4.3 又變快了才繼續使用),Objective C 和 C# 在與 IDE 整合上就表現得很不錯,Java 有蠻多好的 IDE,但語言對於 IDE 則完全沒有支援。

像我就會依照功能整理程式碼,所以我會在 Objective C 裡用 #param mark - UITableViewDelegate Methods 將實作 UITableViewDelegate 的函式集中分區塊,或在 C# 裡用 #region Properties#endregion 將所有的 properties 包起來成為一個區塊,當 IDE 看到這些 preprocessor 時,可以做最佳化顯示,例如在 XCode 裡,如果有使用 #param mark,在上方導覽列的函示列表 (Figure 1) 就會根據 mark 的名稱將函式分區顯示,在找函式時更方便。


Figure 1 - XCode provides integration with preprocessors

Figure 1 - XCode provides integration with preprocessors


這幾年新出的語言都強打在少寫 code 和提高可讀性,更重要的是能更容易發展出 domain specific language,就這一點 Java 確實有點顯得疲態了。其實文中列的特性大多是一些語法糖衣,但對程式的可讀性和抽象度都能提昇不少,我覺得挺實用也很划算的。


2024 的補充

過了 10 年 (突然發現正好整整十年),把文章從 logdown 搬過來時,發現 Java 雖然在語言本身真的有改變,像是導入 record,更強的 switch expression 等等,但 property 依然沒有;literal data structure declaration 也沒有,只能靠 record 稍微簡化一點;category (Swift 改稱為 extension) 也沒有,反倒是 Kotlin 加入了;extension (Swift 沒有對應的設計) 也是沒有,唯一有一點點關係的是 Java 9 導入了新的模組模型,但感覺很少人用;與 IDE 的整合也沒有。

只能說還是挺失望的,但 10 年過去,有些想法也改變了,像是 category 我現在就還好 (參閱 閒談軟體設計:Single Responsibility),若現在問我希望 Java 加什麼特性?就是語言直接支援 null 的處理,Optional 真的很難用 (參閱拙譯《沒有什麼比 Optional 更好,真的,沒有,更好》)...

avatar-img
53會員
104內容數
這是從 Medium 開始的一個專題,主要是想用輕鬆閒談的方式,分享這幾年軟體開發的心得,原本比較侷限於軟體架構,但這幾年的文章不僅限於架構,也聊不少流程相關的心得,所以趁換平台,順勢換成閒談軟體設計。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Spirit的沙龍 的其他內容
很明顯可以看到 parallelSort(T[], Comparator<T> 大概可以帶來 2.5 倍到接近 3 倍的效能增益 (和數量無關)。所以,結論是當需要處理大量資料的排序時,真的可以考慮使用 parallelSort(T[], Comparator<T>。
Java 8 有了 Base64 編解碼器,方便不少,不過 Apache Commons Codec 提供更多常用的編解碼器,其實是更方便的,但如果你的應用程式中只需要 Base64 編解碼器,在有 Java 8 的環境中確實不需要將 Apache Commons Codec 和專案一起打包。
default methods 似乎也引起不小的討論,因為 default methods 加上可以實作多個介面,已經有點像 C++ 的多重繼承了,只差在沒辦法繼承成員變數而已,是好是壞就看怎麼使用了。我個人覺得還蠻方便的
Lazy evaluation 的效益必須是在 pipe 的組合上有最佳化過的,若組合的不好反而更糟糕,且在 I/O 上幫助似乎也不大。parallel stream 要能發揮效果必須看資料的來源類型,不過要注意的是 parallel stream 也會使記憶體的使用量增加,使用上也要小心。
老實說,看到 Java Sream API 讓我感到相當親切,這應該跟我研究所多年的研究題目是 visual dataflow language 有關,Java Stream API 把迴圈給內化了,每個 operation 的重點是要做什麼,大大提高了程式的抽象化程度和可讀性。
最後,Java 8 雖然支援 Lambda,但我覺得 Closure 某種程度上還不稱不上是 Java 的第一級居民,我還是比較喜歡寫一些小而易測的 class,而不是使用 Lambda,至於捕捉變數,透過建構子將變數帶入物件也是一種方式。
很明顯可以看到 parallelSort(T[], Comparator<T> 大概可以帶來 2.5 倍到接近 3 倍的效能增益 (和數量無關)。所以,結論是當需要處理大量資料的排序時,真的可以考慮使用 parallelSort(T[], Comparator<T>。
Java 8 有了 Base64 編解碼器,方便不少,不過 Apache Commons Codec 提供更多常用的編解碼器,其實是更方便的,但如果你的應用程式中只需要 Base64 編解碼器,在有 Java 8 的環境中確實不需要將 Apache Commons Codec 和專案一起打包。
default methods 似乎也引起不小的討論,因為 default methods 加上可以實作多個介面,已經有點像 C++ 的多重繼承了,只差在沒辦法繼承成員變數而已,是好是壞就看怎麼使用了。我個人覺得還蠻方便的
Lazy evaluation 的效益必須是在 pipe 的組合上有最佳化過的,若組合的不好反而更糟糕,且在 I/O 上幫助似乎也不大。parallel stream 要能發揮效果必須看資料的來源類型,不過要注意的是 parallel stream 也會使記憶體的使用量增加,使用上也要小心。
老實說,看到 Java Sream API 讓我感到相當親切,這應該跟我研究所多年的研究題目是 visual dataflow language 有關,Java Stream API 把迴圈給內化了,每個 operation 的重點是要做什麼,大大提高了程式的抽象化程度和可讀性。
最後,Java 8 雖然支援 Lambda,但我覺得 Closure 某種程度上還不稱不上是 Java 的第一級居民,我還是比較喜歡寫一些小而易測的 class,而不是使用 Lambda,至於捕捉變數,透過建構子將變數帶入物件也是一種方式。
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
給社群網頁換上一張新的頭貼,是某日在花藝教室拍的,手裡的花遮住半張臉,但眼睛滿是笑意。 「2024,希望日日有花,有微笑。」我寫道。 2023年最後一夜,大家似乎都在盤點過去一年的種種,期許未來。 「過去一年,我都做了什麼?」我不禁想。 回憶裡有大片大片的空白,只間歇出現一個個短促的瞬間,有
Thumbnail
總是對自己多說好話,告訴自己要堅強,要努力,要有自信,你一定可以!但是實情總不是如此,一再地被拒絕,一再地被打槍,一再地得不到想要的結果,也一再地對自己失望。希望,大概是這世界最有吸引力的東西,它看不到,摸不到,我們卻一昧想要得到,而且是幻想著真正有一天會如期實現,希望代表著我們生活有一股前進的動
Thumbnail
星期一,據說有颱風,但是天氣意外的好。傍晚的天空散著折射的光,透在雲上,就像那一縷縷的薰衣草棉花糖,等待被人捲起。 週二,用膠片相機拍照,他真的推薦了好東西!拍出來的照片質感極高。化裝課說到警察,我曾遇過,真的很年輕。 週三選修,憑著一些些能力調了持香度較久的霍爾和白龍。我真的很開心,下午宣布晚
Thumbnail
常常在想所謂的懷抱希望,是不是就只是甘願被騙而已,選擇拒絕相信當下難受的現實、決定去服下一個讓自己舒服一點的止痛藥,做個好夢。
Thumbnail
煙味飄不下來 腳步聲少了一點 桌上的菜少了兩碟 需要一點勇氣 需要一點時間 需要一點想像 與那安安靜靜的黑夜同處 不寒冷不惆悵 有一個遠方, 你將要啟航。 有一個國度, 輾轉出現在夢的地圖上。 生命是那麽遼闊, 請代替你的母親, 走遍異國的土壤。 生命是如此寬容, 願你攜帶愛與歲月的叮嚀,
「稚嫩的樹,快點長大 甜甜的夢請慢慢縮小。」 兒時希望 織成一幅線條雅的畫 長在美麗的詩裡……
Thumbnail
希望我的夢 不被死當 更不願我的愛 遭到退稿
Thumbnail
「在撐一陣子....應該就可以....」 很多人心裡面是這麼想的 支持著的是一種信仰叫做【希望】 撐著~撐著。也就走到了今天 回過頭望去....那無止盡 延伸的是一步一腳印 【希望】就在前方。加油~快到了 《光之圖文隨想誌》2012.04.24  
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
給社群網頁換上一張新的頭貼,是某日在花藝教室拍的,手裡的花遮住半張臉,但眼睛滿是笑意。 「2024,希望日日有花,有微笑。」我寫道。 2023年最後一夜,大家似乎都在盤點過去一年的種種,期許未來。 「過去一年,我都做了什麼?」我不禁想。 回憶裡有大片大片的空白,只間歇出現一個個短促的瞬間,有
Thumbnail
總是對自己多說好話,告訴自己要堅強,要努力,要有自信,你一定可以!但是實情總不是如此,一再地被拒絕,一再地被打槍,一再地得不到想要的結果,也一再地對自己失望。希望,大概是這世界最有吸引力的東西,它看不到,摸不到,我們卻一昧想要得到,而且是幻想著真正有一天會如期實現,希望代表著我們生活有一股前進的動
Thumbnail
星期一,據說有颱風,但是天氣意外的好。傍晚的天空散著折射的光,透在雲上,就像那一縷縷的薰衣草棉花糖,等待被人捲起。 週二,用膠片相機拍照,他真的推薦了好東西!拍出來的照片質感極高。化裝課說到警察,我曾遇過,真的很年輕。 週三選修,憑著一些些能力調了持香度較久的霍爾和白龍。我真的很開心,下午宣布晚
Thumbnail
常常在想所謂的懷抱希望,是不是就只是甘願被騙而已,選擇拒絕相信當下難受的現實、決定去服下一個讓自己舒服一點的止痛藥,做個好夢。
Thumbnail
煙味飄不下來 腳步聲少了一點 桌上的菜少了兩碟 需要一點勇氣 需要一點時間 需要一點想像 與那安安靜靜的黑夜同處 不寒冷不惆悵 有一個遠方, 你將要啟航。 有一個國度, 輾轉出現在夢的地圖上。 生命是那麽遼闊, 請代替你的母親, 走遍異國的土壤。 生命是如此寬容, 願你攜帶愛與歲月的叮嚀,
「稚嫩的樹,快點長大 甜甜的夢請慢慢縮小。」 兒時希望 織成一幅線條雅的畫 長在美麗的詩裡……
Thumbnail
希望我的夢 不被死當 更不願我的愛 遭到退稿
Thumbnail
「在撐一陣子....應該就可以....」 很多人心裡面是這麼想的 支持著的是一種信仰叫做【希望】 撐著~撐著。也就走到了今天 回過頭望去....那無止盡 延伸的是一步一腳印 【希望】就在前方。加油~快到了 《光之圖文隨想誌》2012.04.24