在javascript中eval()可以實(shí)現(xiàn)字符串轉(zhuǎn)代碼,java中需要使用動(dòng)態(tài)編譯。
創(chuàng)新互聯(lián)于2013年創(chuàng)立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站建設(shè)、做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元新鄉(xiāng)做網(wǎng)站,已為上家服務(wù),為新鄉(xiāng)各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18982081108
把獲得的字符串寫入一個(gè)臨時(shí)文件中,然后編譯它,在調(diào)用其中的函數(shù)。
我們把要轉(zhuǎn)換的字符串構(gòu)造一個(gè)完整的類:如果方法是有返回值的.則:
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)用
}
我們可以先寫好多個(gè)重載的eval,有返回值和沒(méi)有返回值的.以及可以傳遞參數(shù)的.
這樣我們就可以用字符串轉(zhuǎn)換為java的語(yǔ)句來(lái)執(zhí)行.
步驟:
1、在cmd中切換到編寫的代碼所保存的目錄下;
2、在cmd中輸入javac然后點(diǎn)空格,再點(diǎn)擊文件名和包括后綴名確定后,在存放編寫代碼的文件下會(huì)生成一個(gè)class的字節(jié)碼文件;
3、在cmd中輸入java然后點(diǎn)空格,輸入第二步中生成的字節(jié)碼的文件名,不需要后綴名,點(diǎn)擊確定即可運(yùn)行代碼。
代碼就是程序員用開(kāi)發(fā)工具所支持的語(yǔ)言寫出來(lái)的源文件,是一組由字符、符號(hào)或信號(hào)碼元以離散形式表示信息的明確的規(guī)則體系。計(jì)算機(jī)代碼稱為源代碼,是相對(duì)目標(biāo)代碼和可執(zhí)行代碼而言的。 源代碼就是用匯編語(yǔ)言和高級(jí)語(yǔ)言寫出來(lái)的地代碼,目標(biāo)代碼是指源代碼經(jīng)過(guò)編譯程序產(chǎn)生的能被cpu直接識(shí)別二進(jìn)制代碼。
JAVA的動(dòng)態(tài)編譯可以實(shí)現(xiàn),具體實(shí)現(xiàn),參考下面說(shuō)明:
在很多腳本語(yǔ)言中都有eval函數(shù),它可以把字符串轉(zhuǎn)換為表達(dá)式并執(zhí)行.如在javaScript中:
var str = aid.value + ".style.top = 10;"
把一個(gè)id為"aid"的控制的值取出來(lái)加合并成一個(gè)字符串,如果aid的值是"axman",則
str = "axman.style.top = 10"
現(xiàn)在我們要讓控制axman移動(dòng)到頂部為10的位置:
eval(str);
這樣這個(gè)字符串就變成了表達(dá)式或語(yǔ)句開(kāi)始執(zhí)行.這樣的功能對(duì)于動(dòng)態(tài)構(gòu)造變量是有非常重要的
意義.
那么在java中,如果實(shí)現(xiàn)這個(gè)功能呢?其實(shí)我們可以用動(dòng)態(tài)編譯來(lái)實(shí)現(xiàn)。
假設(shè)有一組方法實(shí)現(xiàn)不同的功能,現(xiàn)在要根據(jù)傳進(jìn)來(lái)的方法名調(diào)用相應(yīng)的方法,假如沒(méi)有eval功能,我們只能這么做:
MyClass mc = new MyClass();
if(str.equals("m1"))
mc.m1();
else if(str.equals("m1"))
mc.m2();
else if(str.equals("m3"))
mc.m3();
else if(.........)
.........();
如果有一百種情況呢?
如果我們用eval方法就可以直接這樣:
String str = ...........;
eval("mc"+str+"();");
是不是非常方便?關(guān)鍵是如何實(shí)現(xiàn)eval()?
我們把要轉(zhuǎn)換的字符串構(gòu)造一個(gè)完整的類:如果方法是有返回值的.則:
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)用
}
我們可以先寫好多個(gè)重載的eval,有返回值和沒(méi)有返回值的.以及可以傳遞參數(shù)的.
這樣我們就可以用字符串轉(zhuǎn)換為java的語(yǔ)句來(lái)執(zhí)行.
你這個(gè)其實(shí)是模擬編譯器做的事情。可以用正則表達(dá)式匹配輸入的字符串,如果匹配已經(jīng)定義的函數(shù),就執(zhí)行。