4

我有一个带有名为 test 的方法的 Java 类:

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()”的工作?

4

3 回答 3

3

您还可以使用等效的语法:

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
于 2016-01-23T06:57:29.973 回答
2

我找不到任何绑定类的静态函数并在没有类实例的情况下调用它的示例。任何地方的所有示例,即使在使用静态函数时,都传递对象的实例。因此,我不能 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给它,从而“隐藏”实例的传递。

于 2016-01-08T13:39:29.047 回答
0

我不做那么多lua,但你说你必须做的就是有效的

LuaValue chunk = globals.load("obj:test()");

注意冒号,这就是该方法的调用方式。

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

于 2016-01-08T13:46:55.710 回答