java執(zhí)行字符串公式的三種方法總結
問題描述
最近,在項目中遇到了一項特定需求:前端用戶需要輸入一個數(shù)學公式,這個公式隨后被保存到后臺數(shù)據(jù)庫中。當后臺需要從數(shù)據(jù)庫中檢索這個公式并進行計算時,面臨的一個挑戰(zhàn)是,從數(shù)據(jù)庫獲取的公式是以字符串形式存在的,無法直接代入數(shù)值進行計算。
解決方案
方法1:使用 ScriptEngine(Java內置)
經查閱資料,發(fā)現(xiàn)利用Java的腳本引擎(特別是JavaScript引擎)能夠高效地解析并執(zhí)行各類數(shù)學公式。在JDK 1.6及更高版本中,引入了javax.script包,這一包為開發(fā)者提供了極大的便利,能夠輕松地將腳本引擎嵌入到Java應用程序中。借助這一功能,我們可以無縫地處理字符串形式的公式,并將其轉化為可執(zhí)行的代碼,從而滿足項目中的計算需求。
具體代碼:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class EvaluateExpression {
public static void main(String[] args) {
// 示例公式字符串(從數(shù)據(jù)庫中獲取)
String expression = "3 + 5 * (2 - 8)";
// 創(chuàng)建一個腳本引擎管理器
ScriptEngineManager manager = new ScriptEngineManager();
// 獲取一個JavaScript引擎
ScriptEngine engine = manager.getEngineByName("JavaScript");
try {
// 執(zhí)行公式并獲取結果
Object result = engine.eval(expression);
// 將結果轉換為字符串并打印
System.out.println("公式" + expression + "的執(zhí)行結果是:"+ result);
} catch (ScriptException e) {
// 捕獲并處理腳本異常
System.err.println(e.getMessage());
}
}
}
運行結果

注:如果公式中包含變量作為運算的一部分,我們可以通過使用Java字符串的replace()或者replaceAll()方法,將這些變量替換為具體的數(shù)值,隨后再進行計算。以下是一個具體的代碼實現(xiàn)示例,用于說明這一過程:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class EvaluateExpression {
public static void main(String[] args) {
// 示例公式字符串(從數(shù)據(jù)庫中獲取)
String expression = "3 + a * (2 - b) + a";
// 創(chuàng)建一個腳本引擎管理器
ScriptEngineManager manager = new ScriptEngineManager();
// 獲取一個JavaScript引擎
ScriptEngine engine = manager.getEngineByName("JavaScript");
String a = "5", b = "8";
try {
// 執(zhí)行公式并獲取結果
Object result = engine.eval(expression.replaceAll("a", a).replace("b", b));
// 將結果轉換為字符串并打印
System.out.println("公式" + expression + "的執(zhí)行結果是:"+ result);
} catch (ScriptException e) {
// 捕獲并處理腳本異常
System.err.println(e.getMessage());
}
}
}
運行結果

注意:Java 9+ 已將 Nashorn 引擎標記為廢棄(需手動添加依賴),且存在安全風險。建議對非受信輸入進行嚴格校驗。
方法2:使用第三方庫 [exp4j](推薦)
官網(wǎng)地址: exp4j
適用于數(shù)學表達式(安全且輕量級):
- 添加依賴(Maven):
<dependency>
<groupId>net.objecthunter</groupId>
<artifactId>exp4j</artifactId>
<version>0.4.8</version>
</dependency>
- 示例代碼:
import net.objecthunter.exp4j.Expression;
import net.objecthunter.exp4j.ExpressionBuilder;
public class FormulaCalculator {
public static void main(String[] args) {
String formula = "10 * (3 + 2) / 5";
Expression expression = new ExpressionBuilder(formula).build();
double result = expression.evaluate();
System.out.println(result); // 輸出: 10.0
}
}
優(yōu)勢:
- 無外部依賴,避免代碼注入風險
- 支持自定義變量(如
"x^2 + y") - 支持數(shù)學函數(shù)(
sin,log等)
方法3:使用Expression(Spring框架)(推薦)
適用于 Spring 項目:
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class FormulaCalculator {
public static void main(String[] args) {
String formula = "10 * (3 + 2) / 5";
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(formula);
Integer result = exp.getValue(Integer.class);
System.out.println(result); // 輸出: 10
}
}
總結
javax.script包中的ScriptEngineManager腳本引擎管理器是一個功能強大的工具,它能夠滿足我們在Java代碼中執(zhí)行字符串公式的需求。通過ScriptEngineManager,我們可以輕松地獲取到各種腳本引擎(如JavaScript引擎),并利用這些引擎來解析和執(zhí)行嵌入在字符串中的數(shù)學表達式或其他類型的腳本代碼。這種方法不僅簡化了代碼的實現(xiàn),還提高了程序的靈活性和可擴展性,使我們能夠高效地處理各種復雜的計算任務。
雖然ScriptEngine能滿足需求,但對Java 9+兼容性較差??紤]到目前大多數(shù)企業(yè)都采用Spring全家桶進行開發(fā),我們強烈推薦使用Spring Expression。當然exp4j也是很不錯的選擇。
到此這篇關于java執(zhí)行字符串公式的三種方法的文章就介紹到這了,更多相關java執(zhí)行字符串公式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
InvocationHandler中invoke()方法的調用問題分析
這篇文章主要介紹了InvocationHandler中invoke()方法的調用問題分析,具有一定參考價值,需要的朋友可以了解下。2017-11-11
劍指Offer之Java算法習題精講數(shù)組查找與字符串交集
跟著思路走,之后從簡單題入手,反復去看,做過之后可能會忘記,之后再做一次,記不住就反復做,反復尋求思路和規(guī)律,慢慢積累就會發(fā)現(xiàn)質的變化2022-03-03
Java實現(xiàn)一鍵生成表controller,service,mapper文件
這篇文章主要為大家詳細介紹了如何利用Java語言實現(xiàn)一鍵生成表controller,service,mapper文件,文中的示例代碼講解詳細,需要的可以收藏一下2023-05-05
SpringBoot?Redis清除所有的key的實現(xiàn)方法
本文主要介紹了SpringBoot?Redis清除所有的key的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-05-05

