gpt4 book ai didi

java - Rhino:Java 数字的行为不像 Javascript 数字

转载 作者:太空狗 更新时间:2023-10-29 22:41:28 26 4
gpt4 key购买 nike

我有一个可以在我的 Javascript 程序中访问的这个 Java 类的实例

public class ContentProvider {
public Object c(int n) {
switch (n) {
case 1: return 1.1;
case 2: return 2.2;
case 3: return 3.3;
case 4: return "4";
case 5: return new java.util.Date();
}
return null;
}
}

这是 main() 中的代码:

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
engine.put("ctx", new ContentProvider());

res = engine.eval("ctx.c(1)");

System.out.printf("rhino:> %s (%s)%n"
, res
, res != null ? res.getClass().getName() : null
);

简单表达式 ctx.c(1) 打印:

rhino:> 1.1 (java.lang.Double)

下面是 ctx.c(1) + ctx.c(2) 发生的情况:

rhino:> 1.12.2 (java.lang.String)

最后 (ctx.c(1) + ctx.c(2)) * ctx.c(3):

rhino:> nan (java.lang.Double)

Rhino 正在执行字符串连接而不是数字算术!以下程序按预期工作:

engine.put("a", 1.1);
engine.put("b", 2.2);
engine.put("c", 3.3);
res = engine.eval("(a + b) * c");

输出:

rhino:> 10,89 (java.lang.Double)

最佳答案

这是 Rhino 的一个奇怪特性:用 engine.put("one", new Double(1)) 设置的 Java Number 可以正常工作,而Java 方法的结果取决于方法本身声明的返回类型,通过反射 API 读取:

  • 如果它是一个基本类型,比如double,它会被转换成一个Javascript数字
  • 否则它会像其他宿主对象一样处理,+ 表示串联,可以是示例中的 Object 也可以是 Double

您可以在当前 ContextWrapFactory 上使用 wrapFactory.setJavaPrimitiveWrap(false) 配置此行为。这样,Rhino 代码就可以保存在程序的引导行中,并且不会弄乱 ContentProvider(我猜这是某种配置代理)

来自live Javadoc of WrapFactory.isJavaPrimitiveWrap()

By default the method returns true to indicate that instances of String, Number, Boolean and Character should be wrapped as any other Java object and scripts can access any Java method available in these objects

因此您可以将此标志设置为 false 以指示 Java Number 应转换为 Javascript 数字。只需两行代码

Context ctx = Context.enter();
ctx.getWrapFactory().setJavaPrimitiveWrap(false);

这里是 the Gist使用我用来测试的完整代码

关于java - Rhino:Java 数字的行为不像 Javascript 数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30185079/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com