科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Java SE6调用Java编译器的两种新方法2

Java SE6调用Java编译器的两种新方法2

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

 在很多Java应用中需要在程序中调用Java编译器来编译和运行。在Java SE6中为我们提供了标准的包来操作Java编译器,这就是javax.tools包。使用这个包,我们可以不用将jar文件路径添加到classpath中了。

来源:IT专家网 2008年6月5日

关键字: 方法 编译器 调用 java

  • 评论
  • 分享微博
  • 分享邮件
在使用完getTask后,需要通过StandardJavaFileManager的getJavaFileObjectsFromFiles或getJavaFileObjectsFromStrings方法得到compilationUnits对象。调用这两个方法的方式如下:.

Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(
Iterable<? extends File> files)
Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(
Iterable<String> names)

String[] filenames = …;
Iterable<? extends JavaFileObject> compilationUnits =
fileManager.getJavaFileObjectsFromFiles(Arrays.asList(filenames));

JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager,
diagnostics, options, null, compilationUnits);

  最后需要关闭fileManager.close();

  下面是一个完整的演示程序。

import java.io.*;
import java.util.*;
import javax.tools.*;

public class test_compilerapi
{
 private static void compilejava() throws Exception
 {
  JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
  // 建立DiagnosticCollector对象
  DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
  StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
  // 建立用于保存被编译文件名的对象
  // 每个文件被保存在一个从JavaFileObject继承的类中
  Iterable<? extends JavaFileObject> compilationUnits = fileManager
.getJavaFileObjectsFromStrings(Arrays asList("test3.java"));
  JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager,
diagnostics, null, null, compilationUnits);
  // 编译源程序
  boolean success = task.call();
  fileManager.close();
  System.out.println((success)?"编译成功":"编译失败");
 }
 public static void main(String args[]) throws Exception
 {
  compilejava();
 }
}

如果想得到具体的编译错误,可以对Diagnostics进行扫描,代码如下:

for (Diagnostic diagnostic : diagnostics.getDiagnostics())
System.out.printf(
"Code: %s%n" +
"Kind: %s%n" +
"Position: %s%n" +
"Start Position: %s%n" +
"End Position: %s%n" +
"Source: %s%n" +
"Message: %s%n",
diagnostic.getCode(), diagnostic.getKind(),
diagnostic.getPosition(), diagnostic.getStartPosition(),
diagnostic.getEndPosition(), diagnostic.getSource(),
diagnostic.getMessage(null));

  被编译的test.java代码如下:

public class test
{
 public static void main(String[] args) throws Exception
 {
  aa; //错误语句
  System.out.println("JavaCompiler测试成功!");
 }
}

  在这段代码中多写了个aa,得到的编译错误为:

Code: compiler.err.not.stmt
Kind: ERROR
Position: 89
Start Position: 89
End Position: 89
Source: test.java
Message: test.java:5: 不是语句
Success: false

  通过JavaCompiler进行编译都是在当前目录下生成.class文件,而使用编译选项可以改变这个默认目录。编译选项是一个元素为String类型的Iterable集合。如我们可以使用如下代码在D盘根目录下生成.class文件。

Iterable<String> options = Arrays.asList("-d", "d:\\");
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager,
diagnostics, options, null, compilationUnits);

  在上面的例子中options处的参数为null,而要传递编译器的参数,就需要将options传入。

  有时我们编译一个Java源程序文件,而这个源程序文件需要另几个Java文件,而这些Java文件又在另外一个目录,那么这就需要为编译器指定这些文件所在的目录。

Iterable<String> options = Arrays.asList("-sourcepath", "d:\\src");

  上面的代码指定的被编译Java文件所依赖的源文件所在的目录。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章