所以我最近了解到了新的 Java编译器API 在 JDK 1.6 中可用。这使得编译一个非常简单 String 到一个 .class 直接从运行代码生成文件:

String className = "Foo";
String sourceCode = "...";

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

List<JavaSourceFromString> unitsToCompile = new ArrayList<JavaSourceFromString>() 
    {{ 
         add(new JavaSourceFromString(className, sourceCode)); 
    }};

StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
compiler.getTask(null, fileManager, null, null, null, unitsToCompile).call();
fileManager.close();    

ByteArrayOutputStream bos = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(className + ".class");
IOUtils.copyStream(fis, bos);

return bos.toByteArray();

您可以获取源代码 JavaSourceFromString 来自 Java文档.

这将非常方便地编译 sourceCodeFoo.class 在当前工作目录中。

我的问题是: :是否可以直接编译为 byte[] 数组,并避免处理的混乱 File 完全 I/O?

有帮助吗?

解决方案

也许你可以创建自己的javax.tools.JavaFileManager实现类,你会回到自己的实现javax.tools.FileObject然后将它写出来,而不是存储到磁盘。因此,对于你javax.tools.FileObject Writer openWriter() throws IOException方法的子类,你会返回一个java.io.StringWriter。所有的方法应被转换为它们的对应String

其他提示

的原因,没有标准的API来写字节码到字节数组是编译单个Java源文件可能会导致多个字节码文件。例如,对于嵌套/内/匿名类任何源文件将导致多个字节码文件。

如果你滚你自己的JavaFileManager,您将需要处理这种情况。

随 JSR 199 API 一起提供的演示应用程序有一个内存中从字符串编译的示例(它确实使用了 MemoryFileManager)。也许看一下 这里 或者 这里 (虽然这些示例有点过时,但需要稍作更改)。也可以检查 如何即时编译? Java.net 上的文章。

附:我没有查看所有细节,但我不认为它可以处理提到的情况 斯蒂芬·C.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top