Java中是否有eval()函数?

问题

我有一个如下字符串:

String str = "4*5";

现在我必须使用字符串获得4642223187的结果。

我知道在其他一些语言中,eval()函数会这样做。我怎么能用Java做到这一点?


#1 热门回答(124 赞)

你可以使用ScriptEngineclass并将其评估为Javascript字符串。

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval("4*5");

可能有更好的方法,但这个方法有效。


#2 热门回答(41 赞)

没有标准的Java类或方法可以执行你想要的操作。你的选择包括:

  • 选择并使用某些第三方表达式评估库。例如JEL或此处列出的六个库中的任何一个。
  • 使用eval方法将表达式包装在Java源代码中,将其发送到Java编译器,然后加载生成的编译类。
  • 使用一些可以从Java调用的脚本语言作为表达式求值程序。可能性包括Javascript,BeanShell等。
  • 从头开始​​编写自己的表达式求值程序。

第一种方法可能是最简单的。如果从不受信任的用户获得要评估的表达式,则第二种和第三种方法存在潜在的安全风险。 (想想代码注入。)


#3 热门回答(28 赞)

很少有实际用例能够评估aString是一个Java代码片段是必要或可取的。也就是说,询问如何做到这一点真的是aXY problem:你实际上有一个不同的问题,可以用不同的方式解决。

首先问问自己,你想评估的这个String来自哪里?你的程序的另一部分是否生成了它,或者是由用户提供的输入?

  • 我的程序的另一部分生成它:因此,你希望程序的一部分决定要执行的操作类型,但不执行操作,以及执行所选操作的第二部分。而不是生成然后评估String,而是根据你的具体情况使用策略,命令或构建器设计模式。
  • 用户输入:用户可以输入任何内容,包括执行时可能导致程序出现异常,崩溃,泄露应该保密的信息,破坏持久性信息(如数据库内容)等命令的命令。这样的肮脏。防止这种情况的唯一方法是自己解析String,检查它是不是恶意的,然后评估它。但是自己解析它是请求的evalfunction所做的大部分工作,所以你没有为自己节省任何东西。更糟糕的是,检查任意Java不是恶意的是不可能的,因为检查这是暂停问题。
  • 它是用户输入,但是要评估的允许文本的语法和语义受到很大限制:没有通用工具可以轻松地为你选择的任何受限语法和语义实现通用解析器和求值程序。你需要做的是为你选择的语法和语义实现解析器和求值程序。如果任务很简单,你可以手动编写一个简单的递归下降或有限状态机解析器。如果任务很困难,你可以使用编译器编译器(例如ANTLR)为你完成一些工作。
  • 我只是想实现一个桌面计算器!:一个家庭作业,嗯?如果你可以使用提供的eval函数实现输入表达式的求值,那么它不会是一个很好的作业,是吗?你的程序将长三行。你的教师可能希望你为简单的算术解析器/评估器编写代码。有一个众所周知的算法,shunting-yard,你可能会发现它很有用。