中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

建設(shè)網(wǎng)工程信息上??焖賰?yōu)化排名

建設(shè)網(wǎng)工程信息,上海快速優(yōu)化排名,武威 網(wǎng)站建設(shè),北京公司注冊地址政策最近在學習lua,然后順便看了下luaj,可能用的人比較少,網(wǎng)上關(guān)于luaj的文章較少,其中在網(wǎng)上找到這個博主的相關(guān)文章,很詳細,對于要學習luaj的小伙伴可以兩篇一起查看,本文在此基礎(chǔ)上進行擴展。 …

?????最近在學習lua,然后順便看了下luaj,可能用的人比較少,網(wǎng)上關(guān)于luaj的文章較少,其中在網(wǎng)上找到這個博主的相關(guān)文章,很詳細,對于要學習luaj的小伙伴可以兩篇一起查看,本文在此基礎(chǔ)上進行擴展。
?????本文的luaj版本是:luaj-3.0.1

珠玉在前》》》》Luaj學習筆記(二) - 在Lua中操作Java對象

LuaJ源碼中org.luaj.vm2.lib.jse.LuajavaLib,是我們在lua中操作java的主要方法庫定義。
在這里插入圖片描述

luajava有五種方法讓我們操作java類:bindClasnewInstance 、 new 、 createProxy 、 loadLib

先放上源碼,然后我們一步步解析,bindClas 、 newInstance 、 new 使用方案和案例在前一篇文章就已經(jīng)解釋過了,這里不做過多贅述,對于前篇不詳細的createProxyloadLib做重點介紹:

public Varargs invoke(Varargs args) {try {switch ( opcode ) {case INIT: {// LuaValue modname = args.arg1();LuaValue env = args.arg(2);LuaTable t = new LuaTable();bind( t, this.getClass(), NAMES, BINDCLASS );env.set("luajava", t);env.get("package").get("loaded").set("luajava", t);return t;}case BINDCLASS: {final Class clazz = classForName(args.checkjstring(1));return JavaClass.forClass(clazz);}case NEWINSTANCE:case NEW: {// get constructorfinal LuaValue c = args.checkvalue(1); final Class clazz = (opcode==NEWINSTANCE? classForName(c.tojstring()): (Class) c.checkuserdata(Class.class));final Varargs consargs = args.subargs(2);return JavaClass.forClass(clazz).getConstructor().invoke(consargs);}case CREATEPROXY: {				final int niface = args.narg()-1;if ( niface <= 0 )throw new LuaError("no interfaces");final LuaValue lobj = args.checktable(niface+1);// get the interfacesfinal Class[] ifaces = new Class[niface];for ( int i=0; i<niface; i++ ) ifaces[i] = classForName(args.checkjstring(i+1));// create the invocation handlerInvocationHandler handler = new ProxyInvocationHandler(lobj);// create the proxy objectObject proxy = Proxy.newProxyInstance(getClass().getClassLoader(), ifaces, handler);// return the proxyreturn LuaValue.userdataOf( proxy );}case LOADLIB: {// get constructorString classname = args.checkjstring(1);String methodname = args.checkjstring(2);Class clazz = classForName(classname);Method method = clazz.getMethod(methodname, new Class[] {});Object result = method.invoke(clazz, new Object[] {});if ( result instanceof LuaValue ) {return (LuaValue) result;} else {return NIL;}}default:throw new LuaError("not yet supported: "+this);}} catch (LuaError e) {throw e;} catch (InvocationTargetException ite) {throw new LuaError(ite.getTargetException());} catch (Exception e) {throw new LuaError(e);}}

bindclass

bindclass:返回一個JavaClass的類,該類是對我們參數(shù)指定的java類的一個包裝。bindClass方法返回類實例class,同時可以調(diào)用類實例的new方法生成該class的實例object,然后就可以調(diào)用實例方法(實例化的調(diào)用這一點和學lua時的面向?qū)ο蟮膶懛ê芟嗨?#xff09;

該方法適合調(diào)用java類的靜態(tài)方法靜態(tài)屬性,當然也可以用來實例化對象,但newInstance 和 new更符合語義

源碼:

			case BINDCLASS: {final Class clazz = classForName(args.checkjstring(1));return JavaClass.forClass(clazz);}JavaClassstatic final LuaValue NEW = valueOf("new");static JavaClass forClass(Class var0) {JavaClass var1 = (JavaClass)classes.get(var0);if (var1 == null) {classes.put(var0, var1 = new JavaClass(var0));}return var1;}public LuaValue getConstructor() {return this.getMethod(NEW);}

測試java代碼:

public class TestClass {public String s1;protected String s2;private String s3;public static String s4;public String method001(){        return "method001";    }protected void method002(){    }private void method003(){    }public static String method004(){        return "method004";    }
}

lua腳本:

local className = "com.test.luaj.TestClass"local classx = luajava.bindClass(className)
print("靜態(tài)方法調(diào)用:",classx:method004())
print("靜態(tài)屬性值:",classx.s4)local obj = classx:new()
print("實例方法調(diào)用:",obj:method001())
print("實例屬性值:",obj.s1)

輸出結(jié)果:

靜態(tài)方法調(diào)用:	method004
靜態(tài)屬性值:	s4
實例方法調(diào)用:	method001
實例方法調(diào)用:	s1

其中,我們在lua腳本中用類實例調(diào)用:new()方法時,實際是invoke JavaClass的new方法,而這個new方法通過getMethod方法拿到的是他的構(gòu)造器方法(在下一個方法源碼中)

newInstance || new

通過源碼可以看到 newInstance 和 new方法的大部分邏輯是一致的

入?yún)⑹怯袇^(qū)別的:

  1. newInstance 方法,接受一個字符串的類路徑然后轉(zhuǎn)換為Class實例;
  2. new方法接受一個LuaValue對象,從中拿出userdata數(shù)據(jù),而這個userdata數(shù)據(jù)是一個Class實例。
    而上一個方法bindClass返回的就是一個包裝了Class的LuaValue對象,因此我們可知,在使用new方法的時候,需要先用bindClass方法生成一個Class實例出來,而newInstance就不用了

??????然后代碼對我們在lua中傳入的參數(shù),截取后邊的一段用作構(gòu)造器參數(shù),然后調(diào)用我們在上一個方法看到JavaClass.forClass包裝Class實例,然后獲取該類的構(gòu)造器,然后invoke調(diào)用構(gòu)造器方法,生成對象

源碼:

			case NEWINSTANCE:case NEW: {// get constructorfinal LuaValue c = args.checkvalue(1); final Class clazz = (opcode==NEWINSTANCE? classForName(c.tojstring()): (Class) c.checkuserdata(Class.class));final Varargs consargs = args.subargs(2);return JavaClass.forClass(clazz).getConstructor().invoke(consargs);}JavaClasspublic LuaValue getConstructor() {return getMethod(NEW);}LuaValue getMethod(LuaValue key) {
···Map map = new HashMap();Constructor[] c = ((Class)m_instance).getConstructors();List list = new ArrayList();for ( int i=0; i<c.length; i++ ) if ( Modifier.isPublic(c[i].getModifiers()) )list.add( JavaConstructor.forConstructor(c[i]) );switch ( list.size() ) {case 0: break;case 1: map.put(NEW, list.get(0)); break;default: map.put(NEW, JavaConstructor.forConstructors( (JavaConstructor[])list.toArray(new JavaConstructor[list.size()]) ) ); break;}
···
}

測試代碼:

local className = "com.test.luaj.TestClass"local classx = luajava.bindClass(className)
local obj = luajava.new(classx)
print("實例方法調(diào)用:",obj:method001())
print("實例屬性值:",obj.s1)
print("-----------")local obj2 = luajava.newInstance(className)
print("newInstance>實例方法調(diào)用:",obj2:method001())
print("newInstance>實例屬性值:",obj2.s1)

輸出結(jié)果:

new>實例方法調(diào)用:	method001
new>實例屬性值:	s1
-----------
newInstance>實例方法調(diào)用:	method001
newInstance>實例屬性值:	s1

createProxy

???????createProxy可以像JDKProxy那樣的在lua中創(chuàng)建對一個對象的一個或多個方法的代理
???????事實上,createProxy使用的代理就是JDKProxy,只不過在用法上和我們通常的用法有些許變動,在最終的方法的invoke時,并不是通常的使用JAVA反射中的的Method的invoke,而是Luaj自己LuaValue的invoke,也就是說通過調(diào)用在lua腳本中定義的那個擴展方法,去實現(xiàn)代理,實際上的代理邏輯都在lua中定義(下面lua腳本可以看出來)
???????還有很重要的一點,在lua中通過createproxy生成出來的代理對象,是不能在lua腳本中去直接調(diào)用代理對象的方法的,?????只能通過將該代理對象當做參數(shù)通過調(diào)用類方法或者對象方法之后在java中去觸發(fā)代理對象的方法。(看下邊的測試lua源碼)

源碼:

			case CREATEPROXY: {				final int niface = args.narg()-1;if ( niface <= 0 )throw new LuaError("no interfaces");final LuaValue lobj = args.checktable(niface+1);// get the interfacesfinal Class[] ifaces = new Class[niface];for ( int i=0; i<niface; i++ ) ifaces[i] = classForName(args.checkjstring(i+1));// create the invocation handlerInvocationHandler handler = new ProxyInvocationHandler(lobj);// create the proxy objectObject proxy = Proxy.newProxyInstance(getClass().getClassLoader(), ifaces, handler);// return the proxyreturn LuaValue.userdataOf( proxy );}

在這里插入圖片描述

測試java代碼:

public interface Car {void running(String carName);void blow(Integer num);}
-------------------------------------------------
public  class Taxi implements Car {@Overridepublic void running(String carName) {System.out.println("The taxi["+carName+"] is running.");}@Overridepublic void blow(Integer num) {for (int i = 0; i < num; i++) {System.out.print("didi\n");}System.out.print("");}public static void triggerProxy(Car car){String carName = UUID.randomUUID().toString();car.running(carName);System.out.println("--------");car.blow((int)Math.random()*10+1);}}
-----------------------------------------------------public class LuaJCreateProxyTest {public static void main(String[] args) throws ScriptException {createProxy002();}static void createProxy002() throws ScriptException {Globals globals = JsePlatform.standardGlobals();globals.loadfile("res/lua/createProxyTest02.lua").call();}
}

lua腳本:

    interfaceName = "com.test.luaj.Car"className = "com.test.luaj.Taxi"taxi = luajava.newInstance(className)-- InvocationHandlerlocal exit_cb = {running = function (carname)print("這是對Car的代理邏輯----前")taxi:running(carname)print("這是對Car的代理邏輯----后")end,blow = function(num)print("Car--blow----前")taxi:blow(num)print("Car--blow----后")end}proxyObj = luajava.createProxy(interfaceName ,exit_cb)-- proxyObj.running()   -- 會報錯,不能這樣使用--必須通過傳參給java方法,在java代碼中去調(diào)用代理對象的方法luajava.bindClass(className):triggerProxy(proxyObj)

輸出結(jié)果:

這是對Car的代理邏輯----前
The taxi[74f253d1-c0d8-47ea-9799-01401174abe4] is running.
這是對Car的代理邏輯----后
--------
Car--blow----前
didi
Car--blow----后

loadLib

關(guān)于loadLib這個方法,前邊文章可能由于歷史更新的原因,在luaj-3.0.1版本中代碼是不對的
?????loadLib通過源碼查看我,我們其實可以看到,他只用兩個參數(shù),第一個是類路徑,第二個是靜態(tài)方法名,這個方法要么返回一個LuaValue類型的結(jié)果,要么不返回或者其他返回類型都會被loadLib轉(zhuǎn)為nil。

源碼:

case LOADLIB: {// get constructorString classname = args.checkjstring(1);String methodname = args.checkjstring(2);Class clazz = classForName(classname);Method method = clazz.getMethod(methodname, new Class[] {});Object result = method.invoke(clazz, new Object[] {});if ( result instanceof LuaValue ) {return (LuaValue) result;} else {return NIL;}}

測試java源碼:

    public static LuaInteger xxx() throws ScriptException {System.out.println("xxx執(zhí)行啦!\t"+(int)Math.pow(14,2));return LuaValue.valueOf((int)Math.pow(14,2));}static void test007() throws ScriptException {Globals globals = JsePlatform.standardGlobals();globals.loadfile("res/lua/loadLibTest.lua").call();}

lua腳本

local className = "com.yangsong.luaj.LuaJTest"
local method = 'xxx'
local _, result = luajava.loadLib(className, method)
print(_,result)

輸出結(jié)果:

xxx執(zhí)行啦!	
196	nil

總結(jié)

bindClass適合做類的靜態(tài)方法和靜態(tài)屬性的取值的操作,也是使用new方法的前置操作。
newInstancenew適合用作java對象實例化之后對實例對象的操作和取值
createProxy適合用作JDKProxy的替代用法,需要注意的是在被代理對象和代理對象都在腳本中生成,且代理對象不能直接在lua中去調(diào)用代理方法執(zhí)行,需要以傳參的形式給到j(luò)ava方法調(diào)用java方法觸發(fā)。
loadLib用于類的無參靜態(tài)方法的調(diào)用,如果需要返回值,則需要定義方法返回類型為LuaValue

http://www.risenshineclean.com/news/54909.html

相關(guān)文章:

  • 怎么給網(wǎng)站做懶加載快速網(wǎng)站推廣優(yōu)化
  • 成都網(wǎng)站設(shè)計費用濟寧seo優(yōu)化公司
  • wordpress圖片備用地址遼寧好的百度seo公司
  • 衡水企業(yè)做網(wǎng)站費用安卓排名優(yōu)化
  • php做自己的網(wǎng)站成功的營銷案例及分析
  • 怎么給網(wǎng)站動態(tài)做偽靜態(tài)優(yōu)化公司治理結(jié)構(gòu)
  • 做爰全過程教育網(wǎng)站百度競價排名官網(wǎng)
  • 手機和電腦網(wǎng)站分開做引擎優(yōu)化搜索
  • 家庭寬帶做網(wǎng)站穩(wěn)定鄭州網(wǎng)站制作公司
  • b2b推廣平臺濟南做seo排名
  • 2 網(wǎng)站內(nèi)部鏈接優(yōu)化廣州seo技術(shù)優(yōu)化網(wǎng)站seo
  • 詩歌網(wǎng)站開發(fā)意義百度網(wǎng)站優(yōu)化培訓
  • 眼鏡網(wǎng)站怎么做谷歌海外廣告投放推廣
  • 自己做網(wǎng)站好不好小紅書推廣方式有哪些
  • 為企業(yè)做一個網(wǎng)站多少錢旅游推廣賺傭金哪個平臺好
  • 常州手機網(wǎng)站建設(shè)新手怎么做網(wǎng)絡(luò)銷售
  • 那些語言可以做動態(tài)網(wǎng)站qq群排名優(yōu)化軟件購買
  • 重慶銅梁網(wǎng)站建設(shè)價格新手做seo怎么做
  • 做家鄉(xiāng)網(wǎng)站源代碼網(wǎng)站收錄查詢網(wǎng)
  • 東平建設(shè)局網(wǎng)站網(wǎng)址提交百度
  • 自己建網(wǎng)站做外貿(mào)網(wǎng)店代運營靠譜嗎
  • 做威客有什么靠譜網(wǎng)站怎樣推廣自己的產(chǎn)品
  • 男男做的視頻網(wǎng)站請簡述網(wǎng)絡(luò)營銷的特點
  • 廣州網(wǎng)站建設(shè)騰虎seo推廣培訓課程
  • 山東網(wǎng)站域名備案時間廣州百度首頁優(yōu)化
  • 網(wǎng)站建設(shè)價格標準報價手機seo快速排名
  • 如何編輯網(wǎng)站內(nèi)容國內(nèi)新聞最新消息10條
  • 個人主頁怎么找安徽搜索引擎優(yōu)化seo
  • 制作網(wǎng)站需要什么關(guān)鍵詞挖掘查詢工具愛站網(wǎng)
  • wordpress多站點文章調(diào)用長沙seo服務(wù)