- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
所以使用 LuaJ。
如果我通过,从 Java 到 Lua,用户数据 List<T>
与类型 T
,Luaj 仍然允许通过 :add
将任何类型的对象插入到该数组中功能。例如:
Java代码:
import java.util.ArrayList;
import org.luaj.vm2.Globals;
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
import org.luaj.vm2.lib.jse.JsePlatform;
import org.luaj.vm2.LuaValue;
ArrayList<Integer>ExampleList=new ArrayList<>();
ExampleList.add(1);
LuaValue[] LuaParams=new LuaValue[] {
CoerceJavaToLua.coerce(ExampleList)
};
Globals globals=JsePlatform.standardGlobals();
try { globals.get("TestFunc").invoke(LuaValue.varargsOf(LuaParams)); }
catch(Exception e) {}
路亚:
function TestFunc(arr)
arr:add("str")
arr:add(2);
end
ExampleList 的结果:
{
new Integer(1),
new String("str"), //This should not be allowed!
new Integer(2)
}
自ExampleList
以来不应该允许该字符串是 List<Integer>
问题:有什么方法可以保持类型安全吗?
如果它有助于测试,这里是将 lua 脚本添加到 lua 内存中的代码(就在 try{}
之前):
globals.load(
"function TestFunc(arr)\n"+
" arr:add(\"str\")\n"+
" arr:add(2);\n"+
"end",
"ExampleScript").call();
最佳答案
经过研究,我发现不可能找出数组被声明为什么泛型类型。 Java 不将该信息存储在对象中。在运行时,它只使用数组声明的类型作为当前变量引用。
您所能做的就是查看其中的对象以确定它应该是什么,但这并非万无一失。
如果数组是在另一个对象中定义的,那么您可以查看父对象的字段以获取数组的组件/模板/通用类型。
[编辑于 2016-07-06]我知道的另一个建议方法是使用实际存储类类型的接口(interface)扩展所有列表类。尽管对于该项目而言,这实际上并不实用。经过思考,Java 不存储列表的泛型类类型是有道理的。
我最终使用的解决方案是使用以下内容(在 Object[] 之后)编辑
行:org.luaj.vm2.lib.jse.JavaMethod.invokeMethod(Object instance, Varargs args)
a = convertArgs(args);
//If this is adding/setting to a list, make sure the object type matches the list's 0th object type
java.util.List TheInstanceList;
if(
instance instanceof java.util.List && //Object is a list
java.util.Arrays.asList("add", "set").contains(method.getName()) && //Adding/setting to list
(TheInstanceList=(java.util.List)instance).size()>0 && //List already has at least 1 item
!a[a.length>1 ? 1 : 0].getClass().isInstance(TheInstanceList.get(0)) //New item does not match type of item #0
)
return LuaValue.error(String.format(
"list coercion error: %s is not instanceof %s",
a[a.length>1 ? 1 : 0].getClass().getName(),
TheInstanceList.get(0).getClass().getName()
));
虽然这可以通过遍历两个对象的扩展父类型列表(java.lang.Object
之前的所有内容)来扩展以说明匹配的父类,但类型安全性较低-比我们项目所需的要明智。
我在上面使用的解决方案专门用于在 LUA 脚本投入生产之前清除它们中的错误。
我们最终可能还需要进行 hack,其中某些类在比较时被视为其祖先或继承类之一。
[2016-07-08编辑]我最终添加了具有声明类型的列表的能力,因此不需要类型猜测。
上面代码块的替换代码:
//If this is adding/setting to a list, make sure the object has the proper class type
if(
instance instanceof java.util.List && //Object is a list
java.util.Arrays.asList("add", "set").contains(method.getName()) //Adding/setting to list
) {
//If this is a TypedList, use its stored class for the typecheck
java.util.List TheInstanceList=(java.util.List)instance;
Class ClassInstance=null;
if(instance instanceof lua.TypedList)
ClassInstance=((lua.TypedList)instance).GetListClass();
//Otherwise, check for a 0th object to typecheck against
else if(TheInstanceList.size()>0) //List already has at least 1 item
ClassInstance=TheInstanceList.get(0).getClass(); //Class of the 0th item
//Check if new item does not match found class type
if(
ClassInstance!=null && //Only check if there is a class to check against
!ClassInstance.isInstance(a[a.length>1 ? 1 : 0]) //Check the last parameter's class
)
return LuaValue.error(String.format(
"list coercion error: %s is not instanceof %s",
a[a.length>1 ? 1 : 0].getClass().getName(),
ClassInstance.getName()
));
}
以及 TypedList 的代码:
/**
* This is a special List class used with LUA which tells LUA what the types of objects in its list must be instances of.
* Otherwise, when updating a list in LUA, whatever is the first object in a list is what all other objects must be an instance of.
*/
public interface TypedList {
Class GetListClass();
}
作为 TypeList 的裸 ArrayList:
import java.util.ArrayList;
public class TypedArrayList<E> extends ArrayList<E> implements TypedList {
private Class ListType;
public TypedArrayList(Class c) {
DefaultConstructor(c);
};
public TypedArrayList(Class c, java.util.Collection<? extends E> collection) {
super(collection);
DefaultConstructor(c);
}
private void DefaultConstructor(Class c) { ListType=c; }
@Override public Class GetListClass() {
return ListType;
}
}
关于java - LuaJ 数组/列表类型安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38004865/
我正在学习 Luaj 库,我正在尝试在单元测试中实现双曲示例: @Test public void testHyperbolicLuaScriptExample() throws Exception
我有 Java 类: class SomeClass{ private int i; public SomeClass(int i){ this.i = i; } } 我需要使用 LuaJ
我一直在尝试寻找一种从 LuaJ 中的 Java 方法返回多个值的方法。也就是说,从 Java 返回多个值以在 Lua 代码中检索。 再一次……我的意思是: public LuaValue call(
我正在尝试编译具有两个函数的 Lua 代码,我想调用这两个函数并从中获取一些信息,但是当我在 LuaValue 对象上使用 invokemethod 时,出现此错误 LuaError: attempt
我正在编写一个 Java 程序,它使用 Lua 脚本来确定将什么输出到程序的某些区域。目前,我的代码看起来是这样的: Globals globals = JsePlatform.standardGlo
所以我得到了这个加载 .lua 文件的 java 文件。非常基本,如果我尝试在 Eclipse 中运行它,它就可以工作。 现在,当我将项目编译为可运行的 jar 文件时,它根本不会加载。当您双击它时,
我正在尝试使用 Luaj + java 构建一个 Controller 。我有以下 java 类 public class Duck { public void talk() { System.o
所以使用 LuaJ。 如果我通过,从 Java 到 Lua,用户数据 List与类型 T ,Luaj 仍然允许通过 :add 将任何类型的对象插入到该数组中功能。例如: Java代码: import
我对 Lua 完全陌生。 我有一个非常简单的脚本:“变量 = 1” 我没有找到如何从我的 Java 应用程序中获取此表达式的结果: “var == 3 和 100 或 -1” 我从这个开始: Glob
本文整理了Java中org.luaj.vm2.lib.ZeroArgFunction类的一些代码示例,展示了ZeroArgFunction类的具体用法。这些代码示例主要来源于Github/Stacko
Luaj 中的 os.time() 以毫秒为单位返回时间,但根据 lua 文档,它应该以秒为单位返回时间。 这是Luaj中的错误吗? 你能提出一种适用于 Luaj(for java) 和真正的 Lua
我正在使用 LuaJ 3.0.1,并且在迭代 Lua 脚本中强制 Java 对象中包含的数组时遇到问题。目前,这就是我正在做的事情: 我有一个包含对象数组的 Java 类。类似的东西 public c
我打算将 Lua 集成到我的 java 应用程序中。您能否谈谈在 LuaJ 与纯 Java 中实现脚本之间的性能比较。还有其他性能更好的替代方案吗? 最佳答案 Lua 使用 JIT 的速度非常快由 L
我正在使用 LuaJ,并且我有一个包含大量函数的 .lua 文件。我如何导入这些函数以在带有 LuaJ 的 Java 中使用? 最佳答案 一个选择是将文件编译成 Java 代码并导入它。另一种方法是使
在我的代码中,我需要将一个 int 插入 Lua 的堆栈中。我知道 C 的 lua_pushnumber,但是 LuaJ 中会使用什么?鉴于 LuaJ 不清楚哪些函数代表某些 C 函数,我找不到它的函
我有一个 Java 类,其中包含一个名为 test 的方法: public class MyClass() { public String test() { //Do Some
我正在试验一种游戏机制,让玩家可以在游戏内计算机上运行脚本。脚本执行将在游戏级别上受到资源限制,每刻指令数量有限。 以下概念验证演示了基本级别的沙盒和任意用户代码的限制。它成功地运行了约 250 条制
我正在使用 LuaJ 在 Java 中运行用户创建的 Lua 脚本。但是,运行永不返回的 Lua 脚本会导致 Java 线程卡住。这也使线程不可中断。我运行 Lua 脚本: JsePlatform.s
在 Java 中 LuaJ library我想知道如何在另一个由 lua 闭包通过 Java 调用的 lua 脚本中要求或导入函数的 lua 脚本。例如,这不起作用: public static Lu
我很有可能正在做一些导致此错误的奇怪事情。 以下简单示例失败: --> thingy.lua function doThing() print( "Thing has been done." );
我是一名优秀的程序员,十分优秀!