【发布时间】:2011-10-15 22:43:10
【问题描述】:
我不是 Java 专家,我对编译和运行动态生成代码的整个概念还很陌生,这在其他语言中非常简单,尤其是 Javascript 和 PHP 等脚本语言。
我正在关注这个 sn-p 代码: http://www.java2s.com/Code/Java/JDK-6/CompilingfromMemory.htm 我做了这样的事情:
private final String = "GeneratedClass_" + Long.toHexString(random.nextLong());
private Method compileCode(String code) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) return null;
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
JavaFileObject source = new JavaSource(className, code);
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(source);
CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits);
if (!task.call()) return null;
try {
return Class.forName(className).getDeclaredMethods()[0];
} catch (ClassNotFoundException e) {}
return null;
}
private class JavaSource extends SimpleJavaFileObject {
final String code;
JavaSource(String name, String code) {
super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension),Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {return code;}
}
想象一下字符串代码是这样的
"public class GeneratedClass_65ce701239c32ce0 {
public String hello() {
return "Hello, world!";
}
}"
在抛出 ClassNotFoundException 的 Class.forName 之前它运行良好。我很困惑,因为我似乎没有从 sn-p 中删除一些重要的东西:所以,这个类已经编译了,但是它去哪儿了?
我读过一些关于使用不同类加载器的文章,但是,就像我说的,我对所有这些东西都很陌生,我不知道去哪里以及如何使用它,以及我应该如何定义自己的类加载器的扩展。 我唯一知道的是,一切对我来说似乎都很复杂......
在 Windows 7 和 JDK 1.7 中使用 Eclipse Indigo。
【问题讨论】:
-
在 Java 中动态编译代码是一个相当高级的话题,我很惊讶您在还是 Java 初学者的同时就觉得需要它。你到底想做什么?可能有更好的方法,不涉及在运行时编译。
-
其实我是在尝试移植一个 Javascript“类”来动态生成字符串和更一般的文档,并且它通过动态生成返回字符串的函数来设法做到这一点。它在 Javascript 中就像一个魅力,我成功地将它移植到 PHP 中,所以我也想尝试将它移植到 Java 中。我试图想象一些不同的东西,但这意味着......好吧,创建我自己的编译器......
标签: java classloader dynamic-compilation