java 动态字符串_Java动态编译执行一串字符串,类似于Javascript里的eval函数
Javascript里的eval函數能動態執行一串js腳本。
那Java里怎么做到呢。
有兩種方法:
一種是使用可以執行js腳本的Java類?ScriptEngineManagerpublic?static?void?main(String?args[]){
ScriptEngineManager?manager?=?new?ScriptEngineManager();
ScriptEngine?se?=?manager.getEngineByName("js");
String?str?=?"13>12&&'張三1'=='張三'";
boolean?result;
try?{
result?=?(?Boolean)se.eval(str);
System.out.println(result);
}?catch?(ScriptException?e)?{
e.printStackTrace();
}
}
另一種復雜點?寫一個eval()方法,可以執行System.out.println("Hello, " + str);這行代碼:
Eval.java:package?com.darrenchan;
import?java.lang.reflect.Method;
import?java.util.ArrayList;
import?java.util.Arrays;
import?java.util.List;
import?javax.tools.JavaCompiler;
import?javax.tools.JavaFileObject;
import?javax.tools.SimpleJavaFileObject;
import?javax.tools.StandardJavaFileManager;
import?javax.tools.ToolProvider;
public?class?Eval?{
/*
*?從java6版本開始,已經支持動態編譯了,你可以在運行期直接編譯.java文件,執行.class文件,并且能夠獲得相關的輸入輸出,
*?甚至還能監聽相關的事件。
*?java的動態編譯提供了多種渠道,比如,可以動態編譯一個字符串,也可以是文本文件,也可以是編譯過的字節碼文件(.class文件),
*?甚至可以是存放在數據庫中的明文代碼或字節碼,只要是符合java規范的就都可以在運行期動態加載,其實現方式就是實現JavaFileObject
*?接口,重寫getCharContent、openInputStream、openOutputStream,或者實現JDK
*?已經提供的兩個SimpleJavaFileObject、ForwardingJavaFileObject。下面我演示一下,如何動態編譯一個字符串。
*/
/**
*?Java動態編譯演示
*/
public?static?void?main(String[]?args)?throws?Exception?{
//?Java源代碼
String?sourceStr?=?"public?class?Hello{public?String?sayHello(String?name){return?\"Hello,?\"+name;}}";
//?類及文件名
String?clsName?=?"Hello";
//?方法名
String?methodName?=?"sayHello";
/**
*?當前編譯器:注意,如果是用的jdk1.6的版本(建議使用jdk1.7,1.7是沒有任何問題的),ToolProvider.
*?getSystemJavaCompiler()拿到的對象將會為null,
*?原因是需要加載的Tools.jar不在jdk安裝目錄的jre目錄下,需要手動將lib目錄下的該jar包拷貝到jre下去,詳情請參考:
*?http://www.cnblogs.com/fangwenyu/archive/2011/10/12/2209051.html
*/
JavaCompiler?cmp?=?ToolProvider.getSystemJavaCompiler();
//?Java標準文件管理器
StandardJavaFileManager?fm?=?cmp.getStandardFileManager(null,?null,
null);
//?Java文件對象
JavaFileObject?jfo?=?new?StringJavaObject(clsName,?sourceStr);
//?編譯參數,類似于javac??中的options
List?optionsList?=?new?ArrayList();
//?編譯文件的存放地方,注意:此處是為Eclipse工具特設的
optionsList.addAll(Arrays.asList(new?String[]?{?"-d",?"./bin"?}));
//?要編譯的單元
List?jfos?=?Arrays.asList(new?JavaFileObject[]?{?jfo?});
//?設置編譯環境
JavaCompiler.CompilationTask?task?=?cmp.getTask(null,?fm,?null,
optionsList,?null,?jfos);
//?編譯成功
if?(task.call())?{
//?生成對象
Object?obj?=?Class.forName(clsName).newInstance();
Class?extends?Object>?cls?=?obj.getClass();
//?調用sayHello方法
Method?m?=?cls.getMethod(methodName,?String.class);
//?第一個參數是執行該方法的主調,后面若干個參數是執行該方法時傳入該方法的實參
String?str?=?(String)?m.invoke(obj,?"陳馳");
System.out.println(str);
}
}
}
StringJavaObject.java:package?com.darrenchan;
import?java.io.IOException;
import?java.net.URI;
import?javax.tools.SimpleJavaFileObject;
public?class?StringJavaObject?extends?SimpleJavaFileObject?{
/**
*?源代碼
*/
private?String?content?=?"";
/**
*?遵循Java規范的類名及文件
*/
public?StringJavaObject(String?javaFileName,?String?content){
super(_createStringJavaObjectUri(javaFileName),?Kind.SOURCE);
this.content?=?content;
}
/**
*?產生一個URL資源路徑
*/
private?static?URI?_createStringJavaObjectUri(String?javaFileName)?{
//注意此處未設置包名
return?URI.create("String:///"?+?javaFileName?+?Kind.SOURCE.extension);
}
/**
*?文本文件代碼
*/
@Override
public?CharSequence?getCharContent(boolean?ignoreEncodingErrors)
throws?IOException?{
return?content;
}
}
經過測試,最終的運行結果符合預期,如下所示:
總結
以上是生活随笔為你收集整理的java 动态字符串_Java动态编译执行一串字符串,类似于Javascript里的eval函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 投资一千万元!滴滴关联公司成立全新能源科
- 下一篇: java connection 共享_j