【问题标题】:Nashorn assign a Java function to a mapNashorn 将 Java 函数分配给地图
【发布时间】:2015-09-17 15:12:07
【问题描述】:

我有这个引擎,它运行用户输入(受信任的)javascript 函数来使用 Nashorn 为他们过滤一些数据。不想详细介绍需求,但假设它是某种插件系统。

这个 javascript 获取一个 Java 映射(它就像一个 JS 对象)作为参数来获取一些上下文数据。 所以我想为这个 JS 对象添加一些方便的扩展方法供用户使用。所以我做了以下事情:

Map<String, String> inputMap = ....
inputMap.put("containsMagic", (Function<String, Boolean>) param -> some complex magic check and return boolean);

完美运行!

if(inputMap.containsMagic('Im Por Ylem'))
  do stuff;

但是,我也希望它不接受任何参数,因为 null 是一个有效值,containsMagic() 看起来比 containsMagic(null) 更好。

if(inputMap.containsMagic())
  do stuff;

但我明白了:

TypeError: Can not invoke method ......$$Lambda$15/1932831450@30c15d8b with the passed arguments; they do not match any of its method signatures.

考虑到 Java 的工作原理,我想这很正常。如果我传递 null,它当然可以工作,但这不是很直观。

我不能添加另一个具有 0 个参数和相同名称的函数,因为 Java 映射是单键的。 复杂的魔法检查需要在java中,所以我也不能分配一个javascript函数(JSObject?)。有什么想法可以做到这一点吗?

【问题讨论】:

    标签: javascript java java-8 nashorn


    【解决方案1】:

    您可以将containsMagic 实现为带有可变参数的显式方法:

    public static class InputMap extends HashMap<String, Object> {
        public Boolean containsMagic(String... args) {
            String arg = args.length == 1 ? args[0] : null;
            // do magic 
        }
    }
    
    ...
    Map<String, Object> inputMap = new InputMap(); 
    

    【讨论】:

    • 啊,聪明!需要注意的是,我尝试在构造上扩展 HashMap(比如匿名类;不确定现在叫什么),但 Nashorn 不喜欢这样。自己的课效果很好。谢谢。
    【解决方案2】:

    java.util.function 遗憾的是缺少可变参数函数的标准接口,但您可以添加自己的:

    @FunctionalInterface
    public interface VariadicFunction<T,R> {
        public R apply(T... args);
    }
    

    然后

    inputMap.put("containsMagic", (VariadicFunction<String, Boolean>) param -> some complex magic check and return boolean);
    

    【讨论】:

    • 好主意,但它不起作用。它失败了java.lang.ClassCastException: Cannot cast java.lang.String to [Ljava.lang.Object;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多