一、前言
Java Shell (JShell),自 Java 9 開始引入,是一個互動式的 Java REPL (Read-Eval-Print Loop) 工具。它允許開發者即時執行 Java 程式碼片段,無需完整的類別宣告或編譯步驟。對於學習 Java 語法、快速測試程式碼邏輯、實驗 API 或進行程式碼除錯都非常方便。雖然 JShell 主要在 Java 9 中推出,但 Java 7 和 8 並沒有這個功能。直到 Java 9 後,JShell 不斷地演進,新增了許多實用特性。本文將整理 Java 9 至 Java 17 之間 JShell 的重要新特性,並分析其應用場景。
二、JShell 的基本架構與運作原理
JShell 的核心概念是建立一個互動式的程式碼執行環境。它的架構可以簡單分為以下幾個部分:
- 輸入解析器 (Input Parser): 負責接收使用者輸入的 Java 程式碼片段。
- 程式碼編譯器 (Code Compiler): 將輸入的程式碼片段動態編譯為 bytecode。
- 執行引擎 (Execution Engine): 負責執行已編譯的 bytecode。
- 輸出處理器 (Output Processor): 顯示執行結果或錯誤訊息。
- 狀態維護器 (State Manager): 管理 JShell 的執行狀態,例如變數、方法、類別等。
JShell 的運作流程大致如下:
- 使用者輸入 Java 程式碼片段(例如,變數宣告、運算式、方法呼叫)。
- 輸入解析器分析程式碼片段。
- 程式碼編譯器將程式碼片段動態編譯成 bytecode。
- 執行引擎執行編譯後的 bytecode。
- 輸出處理器將執行結果顯示給使用者。
- 狀態維護器記錄程式碼片段的執行狀態。
示意圖:
graph LR A[使用者輸入] --> B(輸入解析器); B --> C(程式碼編譯器); C --> D(執行引擎); D --> E(輸出處理器); D --> F(狀態維護器); F --> D;
三、Java 9 JShell 的引入與基本功能
Java 9 是 JShell 的誕生版本,其主要特色與功能包括:
-
互動式程式碼執行: 可以直接輸入 Java 程式碼片段並即時執行,例如宣告變數、執行運算式、定義方法等。
-
支援 import 語法: 可以引入 Java 類別或 package。
-
歷史紀錄: 可以使用方向鍵瀏覽和重新執行之前輸入的程式碼。
-
內建命令: 提供許多內建命令來管理 JShell 環境,例如
/list
(列出輸入過的程式碼片段),/vars
(列出變數) ,/methods
(列出方法),/exit
(退出 JShell) 等 [1] 。 -
支援類別與介面: 可以定義類別和介面,並在 JShell 中使用它們。
-
開啟執行 JShell 互動介面
使用
jshell
指令進入互動介面。建議使用的退出方式:
- 首選 /exit 命令: 這是最乾淨和推薦的退出方式,可以確保 JShell 正常終止,並釋放資源。
- Ctrl + D 作為快捷鍵: 如果你希望快速退出,可以使用 Ctrl + D。
-
JShell 自動補全功能
自動補全功能是一個非常實用的特性。按下 Tab 鍵可以進行以下自動補全:
- 關鍵字和指令: 例如 int, class, import, /list, /vars 等等。
- 變數名稱: 如果你宣告了變數,按下 Tab 鍵可以補全該變數的名稱。
- 方法名稱: 如果你呼叫方法或存取物件的成員,按下 Tab 鍵可以補全方法名稱或成員名稱。
- 類別和套件名稱: 如果你使用 import 語法,按下 Tab 鍵可以補全類別名稱或套件名稱。
自動補全的使用方法:
- 輸入部分程式碼: 在 JShell 提示符號後輸入你想要補全的程式碼片段。
- 按下 Tab 鍵: 按下 Tab 鍵。
- 如果有多個選項: 如果有多個可能的選項,JShell 會顯示一個清單,你可以繼續輸入或者使用方向鍵選擇。 選擇補全選項: JShell 會將補全選項填入,然後你就可以繼續編輯或執行。
範例:
- 輸入 Sys 然後按下 Tab 鍵: JShell 會補全為 System,因為這是 Java 標準函式庫中最符合的類別。
- 輸入 System.o 然後按下 Tab 鍵: JShell 會顯示以 o 開頭的 System 類別的成員,例如 out。
- 輸入 System.out.p 然後按下 Tab 鍵: JShell 會顯示以 p 開頭的 System.out 物件的方法,例如 print, println, printf。
- 輸入 List 然後按下 Tab 鍵: 如果已經 import java.util.*, JShell 會顯示可能的 List 介面補全。
四、Java 10 至 17 JShell 的新特性與改進
自 Java 9 之後,JShell 並沒有重大改版,主要是針對穩定性、效能和一些便利性做了改進。以下列出 Java 10 至 Java 17 間 JShell 的一些新特性與改進:
-
效能優化: 各版本針對 JShell 的執行速度和資源消耗進行了優化,讓 JShell 執行起來更快速、更穩定。
-
Bug 修復: 各版本針對 JShell 發現的錯誤進行修復,提升了 JShell 的可靠性。
-
更友善的錯誤訊息: JShell 的錯誤訊息更加清晰,更容易讓開發者理解錯誤的原因。
-
更方便的操作: JShell 可能在特定版本中優化了指令或操作方式,使其使用更加方便,但這些屬於小型的優化,並沒有革命性的改動。
-
與新 Java 特性的整合: JShell 會跟隨新 Java 版本同步更新,確保能正常執行新版本 Java 語法和特性,例如:
-
Java 10 的 var 關鍵字:
-
Java 14 的 Record 類型:
五、JShell 的應用場景與範例
JShell 的應用場景非常廣泛,以下列舉一些常見例子:
-
學習 Java 語法:
JShell 是一個學習 Java 語法的絕佳工具,可以即時驗證程式碼片段,加速學習過程。例如:
-
API 探索:
可以快速探索 Java 標準函式庫或第三方函式庫,例如嘗試不同 API 的使用方法。
-
快速程式碼測試:
在開發過程中,可以使用 JShell 快速測試程式碼片段,例如驗證演算法邏輯或運算式結果。
-
除錯輔助:
JShell 可以當作簡單的除錯工具,快速驗證變數的值或程式碼邏輯。
六、總結
JShell 自 Java 9 引入以來,提供了一個方便的互動式 Java 開發環境。雖然 Java 10 至 17 的版本更新主要集中在效能提升、bug 修復和與新語法的整合,沒有革命性的功能新增,但是 JShell 仍然是 Java 開發者學習、測試、除錯的有效工具。透過 JShell,開發者可以更快速地迭代程式碼,提升開發效率。無論你是 Java 初學者,還是資深的 Java 開發者,JShell 都是一個值得學習和使用的實用工具。
附錄
-
基本的 JShell 指令:
-
/help 或 /:
- 顯示 JShell 的幫助資訊,列出所有可用的指令。
- /help <指令> 顯示特定指令的詳細說明,例如 /help /list。
-
/exit:
- 退出 JShell 環境。
-
/list 或 /l:
- 列出所有已經輸入的程式碼片段,包括宣告、方法、類別等。
- /list -all 列出所有程式碼片段,包括隱藏的(如自動產生的)。
- /list <編號> 列出指定編號的程式碼片段。
-
/vars:
- 列出所有已定義的變數及其值。
- /vars <變數名稱> 列出特定變數的值和類型。
-
/methods:
- 列出所有已定義的方法。
-
/types:
- 列出所有已定義的類別、介面、枚舉等類型。
-
/edit 或 /e:
- 打開一個編輯器來編輯指定的程式碼片段。
- /edit <編號> 編輯指定編號的程式碼片段。
- /edit <名稱> 編輯指定名稱的程式碼片段。
-
/drop:
- 刪除指定程式碼片段。
- /drop <編號> 刪除指定編號的程式碼片段。
- /drop <名稱> 刪除指定名稱的程式碼片段。
-
/reset:
- 重置 JShell 環境,清除所有已輸入的程式碼、變數、方法等。
-
/history 或 /h:
- 顯示命令歷史紀錄。
- /history <數字> 顯示最近的指定數量的命令歷史紀錄。
-
/help 或 /:
-
其他實用的 JShell 指令:
-
/import:
- 導入類別或套件。
- 例如:/import java.util.List
-
/save:
- 將目前的 JShell 狀態 (包括所有輸入的程式碼片段) 儲存到一個檔案。
- /save <檔案路徑> 例如 /save myjshell.jsh。
-
/open:
- 從檔案中讀取 JShell 程式碼,並在目前的環境中執行。
- /open <檔案路徑> 例如 /open myjshell.jsh。
-
/classpath 或 /cp:
- 顯示目前的 Classpath 設定。
- /classpath <路徑> 可以設定 Classpath。
-
/set:
- 設定 JShell 的選項,例如顯示模式、編輯器等。
- 例如: /set editor notepad (Windows) 或 /set editor vim (Linux/macOS)。
- /set feedback normal (設定回饋模式為一般)
-
/reload
- 重新執行所有已經輸入的程式碼。
-
/import:
沒有留言:
張貼留言