java - 在 javax.scripting javascript 环境中导入 map

标签 java rhino

我在 javax.scripting 映射实现中看到了一些奇怪的行为。

在线示例显示了一个 example添加到 js 环境中的列表:

ScriptEngineManager mgr = new ScriptEngineManager();
  ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
  List<String> namesList = new ArrayList<String>();
  namesList.add("Jill");
  namesList.add("Bob");
  namesList.add("Laureen");
  namesList.add("Ed");
  jsEngine.put("namesListKey", namesList);
  System.out.println("Executing in script environment...");
  try
  {
   jsEngine.eval("var names = namesListKey.toArray();" + "for(x in names) {" + "  println(names[x]);" + "}"
     + "namesListKey.add(\"Dana\");");
  } catch (ScriptException ex)
  {
   ex.printStackTrace();
  }
  System.out.println(namesList);

但是,如果您尝试对 map 执行类似的操作,您会看到奇怪的行为。一方面,如果您尝试遍历映射键,例如

 HashMap<String, Object> m = new HashMap<String, Object>();
 jsEngine.put("map", m);

无法获取映射键 - 如果您尝试遍历键,您将获得方法名称-

jsEngine.eval(" for (var k in m.keySet()){ println(k)};");

结果:

notifyAll
removeAll
containsAll
contains
empty
equals
...

在 js 上下文中,您可以使用 m.get(key) 来寻址 map 中的值,但不能使用 m[key],如果键没有存在它会抛出错误。任何人都可以阐明这种行为,还是它只是坏了?谢谢。

最佳答案

JavaScript 中的 for..in 与 Java 中的 for..each 不同,尽管它们看起来很相似。 JavaScript 中的 for..in 遍历对象中的属性名称。方法名称作为 native Java HashMap 对象的属性暴露给 Rhino,就像您拥有以下 JavaScript 对象一样:

{
notifyAll:function(){},
removeAll:function(){},
containsAll:function(){},
contains:function(){},
empty:function(){},
equals:function(){}
}

我的建议是使用 Set.toArray 方法将 HashMap 键集转换为数组,或者使用 Set.iterator() 获取迭代器。这是一个简短的 Rhino 脚本,展示了如何使用 toArray 方法完成此操作:

x=new java.util.HashMap();
x.put("foo","bar");
x.put("bat","bif");
x.put("barf","boo");

var keyArray = x.keySet().toArray();
for(var i=0, l = keyArray.length; i < l; i++){
    var key = keyArray[i]; 
    var value = x.get(key);
    print(value);
}

哪些输出:

bif
bar
boo

下面是如何使用 Set.iterator 做同样的事情:

x=new java.util.HashMap();
x.put("foo","bar");
x.put("bat","bif");
x.put("barf","boo");

var keyIter = x.keySet().iterator();
while(keyIter.hasNext()){
    var key = keyIter.next() 
    var value = x.get(key);
    print(value);
}

关于java - 在 javax.scripting javascript 环境中导入 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3479146/

相关文章:

java - 在 Java 中使用新列表初始化 Map

javascript - 如何从使用 gzip 编码的服务器在 Rhino 中加载 javascript 库?

java - Rhino 在 java 中设置 NativeObject 属性

java - 通过在 bean 中调用方法来调用代理 AOP

java - LocalDate 在 LocalDate 中具有私有(private)访问权限

java - 无法在 Java 中使用两个 for 循环单独取出

java - 在Rhino中分割java字符串

java - 在 Java 中为 Google AppEngine 构建一个 JS 服务器

javascript - Rhino - 有没有办法在不重新解析代码的情况下将修改后的 AST 恢复为原始 AST?

java - 一种布局将另一种布局推离屏幕