BeanShell 是輕量級、純 Java 實作、可嵌入的腳本引擎 (僅 ~175KB 核心包)。它能在運行時解釋執行標準 Java 語法,同時提供類似 Perl/JavaScript 的動態腳本特性 (弱型別、腳本方法、閉包)。正如 Tcl/Tk 之於 C,BeanShell 賦予 Java 應用「運行時可編程」能力:應用可調用腳本,腳本可操控應用物件,雙向打通,共享同一 JVM 記憶體空間。
| 維度 | 能力 |
|---|---|
| Java 語法支援 | 完整語句、表達式、泛型、註解、Lambda (JDK 8+ 環境) |
| 動態腳本特性 | 無類型變數、腳本方法/閉包、腳本物件、命名空間修飾 (this/super/global) |
| Java 整合 | 透明存取所有 Java 物件/API、反射機制、JavaBean 屬性、集合操作、實作 Java 介面 (JDK 1.3+) |
| 執行模式 | 命令列、圖形主控台、Applet、遠程會話伺服器 |
| 工具命令 | load/save (序列化 Bean)、eval(String)、source(檔案)、run(腳本) |
| 事件處理 | AWT/Swing 事件腳本化處理 |
// 應用端嵌入 BeanShell
Interpreter interpreter = new Interpreter();
// 暴露應用核心物件給腳本
interpreter.set("appContext", this);
interpreter.set("userService", userService);
// 用戶腳本 (外部檔案/資料庫/UI 編輯器)
String userScript = "
// 動態業務規則
if (userService.getLevel(currentUser) > 5) {
appContext.enableVipFeatures();
}
return appContext.calculateDiscount(order);
";
Object result = interpreter.eval(userScript); // 執行並獲取返回值
優勢:業務邏輯外部化、無需重新編譯部署、非技術人員可維護規則、支援熱重載。
網頁嵌入 Applet/Console,學生瀏覽器即可練習 Java,零安裝門檻。金融/科學計算領域的複雜表達式求值 (含條件、迴路),腳本比編譯代碼更靈活。
// 腳本中
save(myBean, "config.ser"); // 序列化
load("config.ser"); // 反序列化還原
Interpreter i1 = new Interpreter(); // 全域命名空間
Interpreter i2 = new Interpreter(i1.getNameSpace()); // 繼承父空間
// 或建立獨立空間
NameSpace ns = new NameSpace(i1.getNameSpace(), "ChildSpace");
Interpreter i3 = new Interpreter(ns);
// 腳本實作 Runnable
Runnable task = (Runnable) interpreter.eval("
new Runnable() {
public void run() { System.out.println(\"Hello from script!\"); }
}
");
new Thread(task).start();
| 引擎 | 特點 | 適用場景 |
|---|---|---|
| BeanShell | 語法最接近 Java、輕量、成熟穩定 | Java 應用內嵌腳本、測試工具、教學 |
| Groovy | 功能豐富、DSL 支援、靜態編譯可選 | 建構工具、測試框架、完整替代語言 |
| Nashorn / GraalVM JS | 高效能 JS、多語言互操作 | 前後端共享邏輯、Polyglot 應用 |
| MVEL | 極簡表達式語言、極快 | 規則引擎、模板求值 |
BeanShell 以「最 Java 的腳本語言」定位,為 Java 應用注入動態靈活性。雖非最高效能、功能最豐富,但其零依賴、語法零學習成本、雙向無縫整合特性,使其在嵌入式腳本、測試診斷、教學原型領域長期佔據一席之地。理解其「共享 JVM、物件參考直通」架構本質,是善用動態腳本技術的關鍵。