Javascript里的eval函数能动态执行一串js脚本。
那Java里怎么做到呢。
有两种方法:
一种是使用可以执行js脚本的Java类ScriptEngineManagerpublicstaticvoidmain(Stringargs[]){
ScriptEngineManagermanager=newScriptEngineManager();
ScriptEnginese=manager.getEngineByName("js");
Stringstr="13>12&&'张三1'=='张三'";
booleanresult;
try{
result=(Boolean)se.eval(str);
System.out.println(result);
}catch(ScriptExceptione){
e.printStackTrace();
}
}
另一种复杂点写一个eval()方法,可以执行System.out.println("Hello, " + str);这行代码:
Eval.java:packagecom.darrenchan;
importjava.lang.reflect.Method;
importjava.util.ArrayList;
importjava.util.Arrays;
importjava.util.List;
importjavax.tools.JavaCompiler;
importjavax.tools.JavaFileObject;
importjavax.tools.SimpleJavaFileObject;
importjavax.tools.StandardJavaFileManager;
importjavax.tools.ToolProvider;
publicclassEval{
/*
*从java6版本开始,已经支持动态编译了,你可以在运行期直接编译.java文件,执行.class文件,并且能够获得相关的输入输出,
*甚至还能监听相关的事件。
*java的动态编译提供了多种渠道,比如,可以动态编译一个字符串,也可以是文本文件,也可以是编译过的字节码文件(.class文件),
*甚至可以是存放在数据库中的明文代码或字节码,只要是符合java规范的就都可以在运行期动态加载,其实现方式就是实现JavaFileObject
*接口,重写getCharContent、openInputStream、openOutputStream,或者实现JDK
*已经提供的两个SimpleJavaFileObject、ForwardingJavaFileObject。下面我演示一下,如何动态编译一个字符串。
*/
/**
*Java动态编译演示
*/
publicstaticvoidmain(String[]args)throwsException{
//Java源代码
StringsourceStr="publicclassHello{publicStringsayHello(Stringname){return\"Hello,\"+name;}}";
//类及文件名
StringclsName="Hello";
//方法名
StringmethodName="sayHello";
/**
*当前编译器:注意,如果是用的jdk1.6的版本(建议使用jdk1.7,1.7是没有任何问题的),ToolProvider.
*getSystemJavaCompiler()拿到的对象将会为null,
*原因是需要加载的Tools.jar不在jdk安装目录的jre目录下,需要手动将lib目录下的该jar包拷贝到jre下去,详情请参考:
*/fangwenyu/archive//10/12/2209051.html
*/
JavaCompilercmp=ToolProvider.getSystemJavaCompiler();
//Java标准文件管理器
StandardJavaFileManagerfm=cmp.getStandardFileManager(null,null,
null);
//Java文件对象
JavaFileObjectjfo=newStringJavaObject(clsName,sourceStr);
//编译参数,类似于javac中的options
ListoptionsList=newArrayList();
//编译文件的存放地方,注意:此处是为Eclipse工具特设的
optionsList.addAll(Arrays.asList(newString[]{"-d","./bin"}));
//要编译的单元
Listjfos=Arrays.asList(newJavaFileObject[]{jfo});
//设置编译环境
pilationTasktask=cmp.getTask(null,fm,null,
optionsList,null,jfos);
//编译成功
if(task.call()){
//生成对象
Objectobj=Class.forName(clsName).newInstance();
ClassextendsObject>cls=obj.getClass();
//调用sayHello方法
Methodm=cls.getMethod(methodName,String.class);
//第一个参数是执行该方法的主调,后面若干个参数是执行该方法时传入该方法的实参
Stringstr=(String)m.invoke(obj,"陈驰");
System.out.println(str);
}
}
}
StringJavaObject.java:packagecom.darrenchan;
importjava.io.IOException;
.URI;
importjavax.tools.SimpleJavaFileObject;
publicclassStringJavaObjectextendsSimpleJavaFileObject{
/**
*源代码
*/
privateStringcontent="";
/**
*遵循Java规范的类名及文件
*/
publicStringJavaObject(StringjavaFileName,Stringcontent){
super(_createStringJavaObjectUri(javaFileName),Kind.SOURCE);
this.content=content;
}
/**
*产生一个URL资源路径
*/
privatestaticURI_createStringJavaObjectUri(StringjavaFileName){
//注意此处未设置包名
returnURI.create("String:///"+javaFileName+Kind.SOURCE.extension);
}
/**
*文本文件代码
*/
@Override
publicCharSequencegetCharContent(booleanignoreEncodingErrors)
throwsIOException{
returncontent;
}
}
经过测试,最终的运行结果符合预期,如下所示:
如果觉得《java 动态字符串_Java动态编译执行一串字符串 类似于Javascript里的eval函数》对你有帮助,请点赞、收藏,并留下你的观点哦!