我知道默认情况下Java没有所谓的eval
(我称之为“邪恶”)方法。这听起来像是一件坏事 - 知道你没有其他许多人做的事情。但更糟糕的是,似乎已经通知你不能拥有它。
我的问题是:背后有什么可靠的推理?我的意思是,谷歌这个只会返回大量的旧数据和虚假的原因 - 即使有一个我正在寻找的答案,我也无法从那些只是抛出通用标签词的人那里过滤掉它。
我对那些告诉我如何解决问题的答案不感兴趣;我自己可以这样做:
文件sample.py
(在py
文件夹中)内容:
def factorial(n):
return reduce(lambda x, y:x * y, range(1, n + 1))
和Java代码:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("jython");
engine.eval(new FileReader("py" + java.io.File.separator + "sample.py"));
System.out.println(engine.eval("factorial(932)"));
这相当于:
String expr = "N[Integrate[E^(2 y^5)/(2 x^3), {x, 4, 7}, {y, 2, 3}]]";
System.out.println(MM.Eval(expr));
//Output: 1.5187560850359461*^206 + 4.2210685420287355*^190*I
Runtime.getRuntime().exec
答案 0 :(得分:6)
“eval”仅在脚本语言中可用,因为它使用运行其余代码的相同解释器;在这些语言中,这个特性是免费的,并且很好地集成了,就像在脚本环境中一样,如果你运行一个字符串或一个“真正的”函数,它就没什么区别。
在复制语言中,添加“eval”意味着捆绑整个编译器 - 这将无视编译的目的。我所知道的编译语言(即使是动态的,如ActionScrip3)也没有eval。
顺便提一下,在Java中评估eval的最简单方法就是你忘了提到:JRE 1.6附带了Javascript引擎,所以你可以用两行代码来评估任何Javascript。你甚至可以争辩说你的问题的预设是错误的。 Java 1.6捆绑了一个非常高级的表达式评估程序。
答案 1 :(得分:5)
正如丹尼尔指出的那样,eval-solutions在java中至少存在一个限制。例如,php eval执行代码就好像它是周围方法的一部分,可以完全访问局部变量,这在标准java中是不可能的。如果没有这个功能,eval替代品需要更多的工作和冗长,这使得它们对“快速”和“简单”解决方案的吸引力大大降低。
eval()
主要是解释性语言的一部分,其中局部变量和代码结构(范围)的名称在运行时可用,从而可以“插入”新代码。 Java字节码不再包含此信息,使eval()替代方案无法映射对局部变量的访问。 (注意:我忽略调试信息,因为没有程序应该依赖它,它可能不存在)
一个例子
int i = 0;
eval("i = 1");
System.out.println(i);
java的必需伪代码
context.put("i",new Integer(0));
eval(context,"i = 1");
System.out.println(context.get("i"));
这对于eval中使用的一个变量看起来很好,在较长的方法中尝试10,并且如果忘记了一个变量,则会获得20个额外的变量访问行和一个或其他运行时错误。
答案 2 :(得分:2)
因为任意Java表达式的评估取决于它的上下文,变量范围等。
如果你需要某种变量表达式,只需使用脚本框架和badamm!你有很多不同种类的表达评价。只需要像JavaScript一样默认,并且有你的eval()!
像Java一样企业化,你并不局限于一种选择。
答案 3 :(得分:2)
但更糟糕的是,似乎被告知你无法拥有它。
我认为你误解了这些文章所说的内容(大部分)。显然,有许多方法可以在Java应用程序中进行表达式求值。它们并不总是可用,但至少其中一些已经存在了很长时间。
我认为人们试图说的是,表达式评估不能作为本机(即作为Java的固有部分或标准库)提供,并且不太可能被添加很好的理由。例如:
eval
来读取JSON,因为它可能是将不良内容注入用户浏览器的路径。)当然......
出于这些原因,也可能是其他原因,Java语言设计者决定不在Java SE中本地支持表达式评估。 (即便如此,一些表达式支持已经正式将其转换为Java EE;例如以JSP表达式语言的形式。这些类在javax.el
包中...或javax.servlet.jsp.el
用于较旧/不推荐的版本。)
答案 4 :(得分:0)
我认为您已经将解决方案提供给您的答案 - 将BeanShell jar与您的应用程序捆绑在一起(或者随后将它包含在JRE中),并且您拥有Java表达式评估程序。但是,它仍然需要输入变量的绑定。
(我更感兴趣的是:这样的脚本/表达式的沙盒如何工作?我不希望我的网络用户在我的服务器中执行危险的代码。)