Java Nashorn对象集函数作为成员

Java Nashorn对象集函数作为成员,java,nashorn,Java,Nashorn,我正在使用nashorn脚本引擎,JSObject接口有问题。 我创建了一个基类,通过成员的HashMap手动向JSObject添加函数: public abstract class EngineObject extends AbstractJSObject { private Map<String, Object> members; public EngineObject() { this.members = new HashMap<>

我正在使用nashorn脚本引擎,JSObject接口有问题。 我创建了一个基类,通过成员的HashMap手动向JSObject添加函数:

public abstract class EngineObject extends AbstractJSObject {
    private Map<String, Object> members;

    public EngineObject() {
        this.members = new HashMap<>();
    }

    public abstract String getName();

    public void initialize(Engine engine) {
    }

    @Override
    public Object getMember(String name) {
        return this.members.get(name);
    }

    @Override
    public void setMember(String name, Object value) {
        this.members.put(name, value);
    }

    @Override
    public boolean hasMember(String name) {
        return this.members.containsKey(name);
    }

    @Override
    public void removeMember(String name) {
        this.members.remove(name);
    }
}



public class MyObject extends EngineObject {
    this.setMember("test", (Runnable) () -> {
        System.out.println("Test");
    });
}

//JavaScript - works
MyObject.test.run();

//JavaScript -- doesn't work
MyObject.test();
公共抽象类EngineObject扩展了AbstractJSObject{
私人地图会员;
公共工程对象(){
this.members=new HashMap();
}
公共抽象字符串getName();
公共无效初始化(引擎){
}
@凌驾
公共对象getMember(字符串名称){
返回此.members.get(名称);
}
@凌驾
public void setMember(字符串名称、对象值){
this.members.put(名称、值);
}
@凌驾
公共布尔hasMember(字符串名称){
返回此.members.containsKey(名称);
}
@凌驾
public void removember(字符串名称){
本.成员.删除(名称);
}
}
公共类MyObject扩展了EngineObject{
this.setMember(“test”,(Runnable)(->{
系统输出打印(“测试”);
});
}
//JavaScript-works
MyObject.test.run();
//JavaScript——不起作用
MyObject.test();
如何向hashmap添加一个函数,让javascript将其识别为函数? 如何通过getMember(从HashMap)调用函数?

正如“aventurin”所述,您的想法是正确的,但您的代码不完整。简单的可编译、可运行示例:

import javax.script.*;
import jdk.nashorn.api.scripting.*;

public class Main {
   public static void main(String[] args) throws Exception {
       JSObject jsobj = new AbstractJSObject() {
           @Override
           public Object getMember(String name) {
               // return a Runnable for "func"
               if (name.equals("func")) {
                  return new Runnable() {
                      @Override
                      public void run() {
                         System.out.println("in run!");
                      }
                  };
               }
               return null;
           }
       };

       ScriptEngineManager m = new ScriptEngineManager();
       ScriptEngine e = m.getEngineByName("nashorn");
       e.put("obj", jsobj);
       e.eval("obj.func()");
   }
}
正如“aventurin”所提到的,您的想法是正确的,但是您的代码是不完整的。简单的可编译、可运行示例:

import javax.script.*;
import jdk.nashorn.api.scripting.*;

public class Main {
   public static void main(String[] args) throws Exception {
       JSObject jsobj = new AbstractJSObject() {
           @Override
           public Object getMember(String name) {
               // return a Runnable for "func"
               if (name.equals("func")) {
                  return new Runnable() {
                      @Override
                      public void run() {
                         System.out.println("in run!");
                      }
                  };
               }
               return null;
           }
       };

       ScriptEngineManager m = new ScriptEngineManager();
       ScriptEngine e = m.getEngineByName("nashorn");
       e.put("obj", jsobj);
       e.eval("obj.func()");
   }
}

使用setMember添加Runnable应该可以工作。不幸的是,您发布的代码相当不完整,语法不好,因此可能没有人知道您做错了什么。使用setMember添加Runnable应该可以。不幸的是,您发布的代码相当不完整,语法也不好,因此可能没有人知道您做错了什么。