LuaJ - 调用Java方法

时间:2016-01-07 20:56:52

标签: java lua luaj

我有一个Java类,其方法名为test:

public class MyClass() {
    public String test() {
        //Do Something
    }
}

然后,我想在我的Lua脚本中调用测试方法。为了做到这一点,我做了:

Globals globals = JsePlatform.standartGlobals();

LuaValue test = CoerceJavaToLua.coerce(new MyClass());
globals.set("obj", test);
LuaValue chunk = globals.load("obj.test()");
chunk.call();

调用Lua脚本时,我的参数错误。

只有在我使用" obj:test()"。

时才有效

我应该在第一个参数中传递对象。

有没有办法做到" obj.test()"工作?

3 个答案:

答案 0 :(得分:1)

您还可以使用等效语法:

obj.test(obj)

相同
obj:test()

您应该能够获得Java类或实例的任何字段或方法,但在某些情况下,需要额外的参数,冒号语法是一个方便的快捷方式。

为了说明,使用各种静态和实例字段和方法构造一个类,如下所示:

public static class MyClass {
    public static String variable = "variable-value";
    public String field = "field-value";
    public static String func() {
        return "function-result";
    }
    public String method() {
        return "method-result";
    }

如果您在示例中强制执行该类的实例,则可以使用以下语法访问每个实例:

Globals globals = JsePlatform.standardGlobals();

// Load an instance into globals
LuaValue instance = CoerceJavaToLua.coerce(new MyClass());
globals.set("obj", instance);
LuaValue chunk = globals.load(
        "print( obj );" +
        "print( obj.variable );" +
        "print( obj.field );" +
        "print( obj.func );" +
        "print( obj.method );" +
        "print( obj:method() );" + // same as 'obj.method(obj)'
        "print( obj.method(obj) );");
chunk.call();   

对我而言

Example$MyClass@4554617c
variable-value
field-value
function: JavaMethod
function: JavaMethod
method-result
method-result

你可能也想强迫这个班级。除了字段之外,仍然可以访问所有内容,而字段对于类来说不存在:

// Load a class into globals, 'field' cannot be accessed
LuaValue cls = CoerceJavaToLua.coerce(MyClass.class);
globals.set("cls", cls);
chunk = globals.load(
        "print( cls );" +
        "print( cls.variable );" +
        "print( cls.func );" +
        "print( cls:func() );" + // same as 'cls.method(cls)'
        "print( cls.func(cls) );" +
        "print( cls.method );" +
        "print( cls.method(obj) );"); 
chunk.call();   

输出结果为:

class Example$MyClass
variable-value
function: JavaMethod
function-result
function-result
function: JavaMethod
method-result

在lua中,可以通过' new'从Java类构造实例,然后它的行为与其他Java实例一样:

// Construct an instance from a class using 'new'
chunk = globals.load(
        "print( cls.new );" +   
        "print( cls.new() );" +
        "print( cls.new().field );"); // etc.
chunk.call();   

,输出

function: JavaConstructor
Example$MyClass@4b67cf4d
field-value

答案 1 :(得分:0)

我找不到任何绑定类的静态函数并在没有类的实例的情况下调用它的示例。 即使在使用静态函数时,所有示例都会传递对象的实例。 因此,我无法100%确定这是不可能的(没有编辑luaj)。

库和示例中的任何静态函数实际上都是通过创建一个虚拟类来实现的,例如见http://luaj.cvs.sourceforge.net/viewvc/luaj/luaj-vm/examples/jse/hyperbolic.java?view=markup

仔细观察luaj源代码表明,luaj在类中的静态函数和非静态函数之间没有区别,这意味着所有函数都被处理为非静态函数。有关详情,请参阅JavaClass.java getMethod功能。

这是一个很简单的例子,说明如何完成你想要的东西,但遗憾的是它不需要静态方法。

package luaj;

import org.luaj.vm2.*;
import org.luaj.vm2.lib.*;
import org.luaj.vm2.lib.jse.*;

public class luaj {

    static final public class MyClass {

        public static int asd = 5;

        static public class Test extends ZeroArgFunction {

            @Override
            public LuaValue call() {
                System.out.println("Worked");
                return NIL;
            }
        }
    }

    public static void main(String[] args) {
        Globals globals = JsePlatform.standardGlobals();
        LuaValue test = CoerceJavaToLua.coerce(new MyClass());
        globals.set("obj", test);
        LuaTable t = new LuaTable();
        t.set("test", new MyClass.Test());
        t.set("__index", t);
        test.setmetatable(t);
        LuaValue chunk = globals.load("print('Testing', obj.asd) obj.test()");
        chunk.call();
    }
}

使用静态方法可以通过将obj.test设置为包含真实obj.test的函数并将MyClass的新实例传递给它来“隐藏”来实现类似的方法“一个实例的传递。

答案 2 :(得分:0)

我不会那么做lua,但你说你要做的就是有效的

"rx"

注意冒号,这就是应该如何调用该方法。

就像我说的那样,我做得不多,但看起来你必须这样做就是这样