如何从被调用的方法中获取调用者对象引用?

时间:2011-04-19 06:14:26

标签: java

我必须将给定的String作为JavaScript代码执行,例如eval('Foo.setMessage("Hello!")'),来自名为Engine的类。这里,setMessage()Foo类的公共静态方法。因为我想从Engine方法中访问setMessage()对象的某些属性,所以如何获取对Engine对象的引用?

我知道如何使用ReflectionCurrentThreadStackThrowable获取调用者类名称(请参阅下面的代码),但这些名称不会返回调用者对象引用。

// --------------------------------------------- -------------------

@John:我已按照您的四个步骤制作了以下代码。但是,在Foo类中,我无法获得正在调用Engine方法的正确setMessage()对象。感谢。

import javax.script.*;

public class Engine {
    public static ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("ECMAScript");
    public String engineName;
    public String message;

    public Engine(String name) {
        this.engineName = name;
    }

    public void eval(String script) {
        try {
            Engine.scriptEngine.eval(script);
            //to do something more
        } catch (ScriptException e) {
            System.out.println(e.toString());
        }
    }

    public static void main(String[] args) {
        Engine firstEngine = new Engine("First engine");
        Engine.scriptEngine.put("firstEngine", firstEngine);
        firstEngine.eval("Packages.Foo.setMessage('Hello!');");

        Engine secondEngine = new Engine("Second engine");
        Engine.scriptEngine.put("secondEngine", secondEngine);
        secondEngine.eval("Packages.Foo.setMessage('Hello!');");
    }
}

public class Foo {
    public static void setMessage(String msg){
        Engine myEngine = (Engine)Engine.scriptEngine.get("What engine to get: first engine or second engine???");
        myEngine.message = msg;
        System.out.println(myEngine.engineName);
    }
}

请帮助,谢谢, 约翰

3 个答案:

答案 0 :(得分:5)

如果你的意思是,你不能得到来电者的“这个”。

答案 1 :(得分:2)

如果方法需要调用者,请将其作为参数传递?

答案 2 :(得分:-1)

第1步:将当前脚本引擎公开为全局变量。
第2步:将您的引擎对象保存在脚本引擎中 第3步:将引擎对象作为javascript中的参数传递 第4步:从Foo.setMessage(SctriptEngine,String)方法获取您的引擎实例。

第1步:

    // expose the current script engine as a global variable
    scriptEngine.put("scriptEngine", scriptEngine);


第2步:

    //save your engine object
    scriptEngine.put("myEngine", /*YourEngine instance*/);


第3步:

var imps = JavaImporter(java.io,java.util,/*imports*/);
with(imps){

    Foo.setMessage(scriptEngine,"message");
}


第4步:

public class Foo {
    // save ScriptEngine instance if you don't want to pass it as parameter
    public static void setMessage(ScriptEngine engine,String msg) {
        YourEngine myEngine = (YourEngine)engine.get("myEngine");
        // use myEngine...
        // or
        // ScriptContext sc = engine.getContext();
        // YourEngine myEngine = (YourEngine)sc.getAttribute("myEngine");

    }

}

更新:为所有Engine个对象保留相同的键名(例如myEngine)。最好在密钥名称前加上当前线程名称 id ,只要结果密钥名称在线程中是唯一的。

String keyName = Thread.currentThread().getName() + "myEngine";

String keyName = Thread.currentThread().getId() + "myEngine";//preferred