希望 Java 未來能新增的特性

更新於 發佈於 閱讀時間約 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
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本章節的目的是介紹Java中的套件使用,包括如何引用第三方套件和自定義模組,如何創建和使用自定義套件,以及介紹一些常見的Java標準庫套件。這些內容將幫助讀者更好地理解和使用Java的套件系統。
Thumbnail
此章節旨在介紹Java程式語言中的各種資料型別,包括基本型別、引用型別、集合型別、陣列型別、字典型別等。它還講解了如何在Java中進行型別轉換和自定義型別,並提供了相關的程式碼示例。
Thumbnail
此章節旨在介紹Java的基本語法、註解和變數的使用。透過學習,讀者將了解Java程式的基本結構、程式進入點的定義、如何撰寫單行和多行註解,以及如何宣告和初始化變數。
Thumbnail
這篇文章的目的是對Java程式設計語言進行介紹,包括它的特性、應用範疇、主要使用者,以及相關的學習資源和常見的庫與框架。此外,它也提供了一些學習Java的渠道,以及與Java相關的其他知識。
Thumbnail
TypeScript是一種由Microsoft開發和維護的開源編程語言。它是JavaScript的超集,主要擴展了JavaScript的語法,增加了靜態類型檢查和其他特性,使得開發大型應用程序更為方便和可靠。
Thumbnail
JavaScript是一種具有動態型別、弱型別、原型繼承等特性的高級腳本語言,應用範圍廣泛,包括前端開發、後端開發、移動應用等。它被各種公司和開源社區廣泛使用。學習JavaScript需要掌握ECMAScript標準、異步編程、模塊系統等知識。
Thumbnail
親愛的 Java 開發者和愛好者們,您是否對於 Java 的魅力充滿好奇?是否有著一個關於 Java 的獨特見解或創新想法?現在是您展現才華的時刻了! 我們誠摯地邀請您參與我們的 Java 投稿活動,分享您的專業知識、經驗和見解。無論您是一位有著多年 Java 開發經驗的專家,還是一位剛剛踏入
Thumbnail
學習JavaScript的理由有很多,包括容易學習的程式語言、互動式體驗、多功能性、跨平臺、社群和資源豐富、高市場需求。此外,文章提供了設計和前端教學的相關資源連結。文章中還提到了一些與學習JavaScript相關的教學文章和影音教學資源。
Thumbnail
關於程式語言的學習,只要掌握住幾個基本特性要熟悉幾種程式語言也不困難,這三個基本特性就是…
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本章節的目的是介紹Java中的套件使用,包括如何引用第三方套件和自定義模組,如何創建和使用自定義套件,以及介紹一些常見的Java標準庫套件。這些內容將幫助讀者更好地理解和使用Java的套件系統。
Thumbnail
此章節旨在介紹Java程式語言中的各種資料型別,包括基本型別、引用型別、集合型別、陣列型別、字典型別等。它還講解了如何在Java中進行型別轉換和自定義型別,並提供了相關的程式碼示例。
Thumbnail
此章節旨在介紹Java的基本語法、註解和變數的使用。透過學習,讀者將了解Java程式的基本結構、程式進入點的定義、如何撰寫單行和多行註解,以及如何宣告和初始化變數。
Thumbnail
這篇文章的目的是對Java程式設計語言進行介紹,包括它的特性、應用範疇、主要使用者,以及相關的學習資源和常見的庫與框架。此外,它也提供了一些學習Java的渠道,以及與Java相關的其他知識。
Thumbnail
TypeScript是一種由Microsoft開發和維護的開源編程語言。它是JavaScript的超集,主要擴展了JavaScript的語法,增加了靜態類型檢查和其他特性,使得開發大型應用程序更為方便和可靠。
Thumbnail
JavaScript是一種具有動態型別、弱型別、原型繼承等特性的高級腳本語言,應用範圍廣泛,包括前端開發、後端開發、移動應用等。它被各種公司和開源社區廣泛使用。學習JavaScript需要掌握ECMAScript標準、異步編程、模塊系統等知識。
Thumbnail
親愛的 Java 開發者和愛好者們,您是否對於 Java 的魅力充滿好奇?是否有著一個關於 Java 的獨特見解或創新想法?現在是您展現才華的時刻了! 我們誠摯地邀請您參與我們的 Java 投稿活動,分享您的專業知識、經驗和見解。無論您是一位有著多年 Java 開發經驗的專家,還是一位剛剛踏入
Thumbnail
學習JavaScript的理由有很多,包括容易學習的程式語言、互動式體驗、多功能性、跨平臺、社群和資源豐富、高市場需求。此外,文章提供了設計和前端教學的相關資源連結。文章中還提到了一些與學習JavaScript相關的教學文章和影音教學資源。
Thumbnail
關於程式語言的學習,只要掌握住幾個基本特性要熟悉幾種程式語言也不困難,這三個基本特性就是…