轉(zhuǎn):
成都創(chuàng)新互聯(lián)成立與2013年,是專(zhuān)業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元淶源做網(wǎng)站,已為上家服務(wù),為淶源各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220
在javascript中eval()可以實(shí)現(xiàn)字符串轉(zhuǎn)代碼,java中需要使用動(dòng)態(tài)編譯。
把獲得的字符串寫(xiě)入一個(gè)臨時(shí)文件中,然后編譯它,在調(diào)用其中的函數(shù)。
我們把要轉(zhuǎn)換的字符串構(gòu)造一個(gè)完整的類(lèi):如果方法是有返回值的.則:
public object eval(string str){
//生成java文件
string s = "class temp{";
s += "object rt(){"
s += "myclass mc = new myclass();"
s += " return mc."+str+"();";
s += "}"
s +="}";
file f = new file("temp.java");
printwriter pw = new printwriter(new filewriter(f));
pw.println(s);
pw.close();
//動(dòng)態(tài)編譯
com.sun.tools.javac.main javac = new com.sun.tools.javac.main();
string[] cpargs = new string[] {"-d", "所在目錄","temp.java"};
int status = javac.compile(cpargs);
if(status!=0){
system.out.println("沒(méi)有成功編譯源文件!");
return null;
}
//調(diào)用temp的rt方法返回結(jié)果:
myclassloader mc = new myclassloader();
class clasz = mc.loadclass("test.class",true);
method rt = clasz.getmethod("rt", new class[]{ string[].class });
return rt.invoke(null, new object[] { new string[0] });
//如果方法沒(méi)有返回就直接調(diào)用
}
我們可以先寫(xiě)好多個(gè)重載的eval,有返回值和沒(méi)有返回值的.以及可以傳遞參數(shù)的.
這樣我們就可以用字符串轉(zhuǎn)換為java的語(yǔ)句來(lái)執(zhí)行.
如果只是簡(jiǎn)單的加減乘除,采用遞歸方式,按照運(yùn)算符優(yōu)先級(jí)計(jì)算,最后得到結(jié)果如果復(fù)雜一點(diǎn),可以采用動(dòng)態(tài)編譯,你寫(xiě)的字符串算式,就變成java代碼,最后采用反射執(zhí)行兩種方式。
首先你可以使用輸入輸出流(或者你說(shuō)的可能是要用反射得到程序結(jié)果來(lái)解析)解析做出*.Java文件。
然后可以使用runtime調(diào)用Dos下的java編譯命令編譯取得class文件。
然后使用classloader,反射等組合執(zhí)行生成的class文件。
Java代碼正常是靜態(tài)編譯成字節(jié)碼,由對(duì)應(yīng)平臺(tái)的JVM加載執(zhí)行,靜態(tài)編譯無(wú)法動(dòng)態(tài)擴(kuò)展功能。動(dòng)態(tài)編譯有兩種方式實(shí)現(xiàn):
從源碼編譯,需要調(diào)用Java Compiler,程序需要運(yùn)行于JDK(而不是JRE)之上。
動(dòng)態(tài)字節(jié)碼生成技術(shù)(如CGLib、ASM)創(chuàng)建類(lèi)。
動(dòng)態(tài)編譯可以簡(jiǎn)化代碼,增強(qiáng)類(lèi)功能,但也帶來(lái)了代碼復(fù)雜度,線上不易維護(hù)。