问题描述
- 希望有个 java 牛人帮我解决
- 1、在 java 程序中如何让 String 中的字符串当作程序来运行
2、如何通过代码来让. java 文件编译成 class 字节码文件。
注 如果可以请附上代码,或者给出思路,小弟会十分感谢。
小弟初入此行半年,还没有c 币,希望大家支持下,谢谢
解决方案
我不是牛人,我的理解楼主的第一个问题,是不是想要个Js里的eval()方法,这是别人写的代码,直接上代码。哈哈
实现步骤:
1.自定义一个Java类,该Java类中定义一个方法来包含需要被运行的代码。
2.动态编译刚刚生成的Java源码,不在磁盘上生成源码,而是直接编译内存中的Java源码。
3.动态加载刚刚创建编译的Java二进制码,编译好的Java二进制码不是在磁盘上,而是放在内存中,并定义自己的类加载器,负责加载内存中的class文件。
4.通过反射运行前一步加载的类。
[java] view plaincopyprint?import java.util.Arrays;
import javax.tools.SimpleJavaFileObject;
import javax.tools.JavaFileObject;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import javax.tools.DiagnosticCollector;
import java.net.URI;
public class MyClassLoader
extends ClassLoader
{
@Override
public Class<?> findClass(String str) throws ClassNotFoundException
{
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//用于诊断源代码编译错误的对象
DiagnosticCollector diagnostics = new DiagnosticCollector();
//内存中的源代码保存在一个从JavaFileObject继承的类中
JavaFileObject file = new JavaSourceFromString(""Temp"" str.toString());
Iterable compilationUnits = Arrays.asList(file);
//建立一个编译任务
JavaCompiler.CompilationTask task = compiler.getTask(null null null null null compilationUnits);
//编译源程序
boolean result = task.call();
if (result)
{
return Class.forName(""Temp"");
}
return null;
}
}
class JavaSourceFromString extends SimpleJavaFileObject
{
private String name;
private String code;
public JavaSourceFromString(String name String code)
{
super(URI.create(""string:///"" + name.replace('.' '/') + Kind.SOURCE.extension) Kind.SOURCE);
this.code = code;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) { return code; }
}
import java.util.Arrays;
import javax.tools.SimpleJavaFileObject;
import javax.tools.JavaFileObject;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import javax.tools.DiagnosticCollector;
import java.net.URI;
public class MyClassLoader
extends ClassLoader
{
@Override
public Class<?> findClass(String str) throws ClassNotFoundException
{
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//用于诊断源代码编译错误的对象
DiagnosticCollector diagnostics = new DiagnosticCollector();
//内存中的源代码保存在一个从JavaFileObject继承的类中
JavaFileObject file = new JavaSourceFromString(""Temp"" str.toString());
Iterable compilationUnits = Arrays.asList(file);
//建立一个编译任务
JavaCompiler.CompilationTask task = compiler.getTask(null null null null null compilationUnits);
//编译源程序
boolean result = task.call();
if (result)
{
return Class.forName(""Temp"");
}
return null;
}
}
class JavaSourceFromString extends SimpleJavaFileObject
{
private String name;
private String code;
public JavaSourceFromString(String name String code)
{
super(URI.create(""string:///"" + name.replace('.' '/') + Kind.SOURCE.extension) Kind.SOURCE);
this.code = code;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors){ return code;}
}
public class Eval
{
public static Object eval(String str) throws Exception
{
StringBuffer sb = new StringBuffer();
sb.append(""public class Temp"");
sb.append(""{"");
sb.append("" public Object getObject()"");
sb.append("" {"");
sb.append("" "" + str + ""return new Object();"");
sb.append("" }"");
sb.append(""}"");
//调用自定义类加载器加载编译在内存中class文件
Class clazz = new MyClassLoader().findClass(sb.toString());
Method method = clazz.getMethod(""getObject"");
//通过反射调用方法
return method.invoke(clazz.newInstance());
}
public static void main(String[] args) throws Exception { Object rval = eval(""System.out.println(/""Hello World/"");""); System.out.println(rval); }
}
解决方案二:
字符串怎么能当代码运行是不是你字符串里有别的代码啊
解决方案三:
String 就是一个程序的名称,这样它就可以当成程序(其实就是程序)来运行。
通过代码来实现编译,这是编译原理的实现。可以考虑:共有16款Java 编译器开源软件
解决方案四:
第一个问题不理解
第二个问题用javac就可以了
解决方案五:
1、如果String中的字符串本身就是程序名,可作为程序调用
2、javac实现编译
解决方案六:
第一个不太理解,是调用类吗?
Class clazz = Class.forName(""stirng类名"");
第二个可以用javac命令
解决方案七:
string当程序运行?Java程序吗?还是dos命令
解决方案八:
1.是动态生成String字符串吗,直接赋值就行了。
2.javac可以实现把.java 转换为.class字节码文件 ,可以用eclipsemyeclipse等工具直接编译运行类文件显示结果,之后可以在项目中找到相应的.class文件
解决方案九:
第一个问题我又百度了一个,你试试
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine se = manager.getEngineByName(""js"");
String str = ""1+2*(3+6)-5/2"";
Double result =(Double) se.eval(str);
System.out.println(result);
}
解决方案十:
第一个没太明白,第二个可以在jdk目录环境下用javac编译!!