模块  java.compiler
软件包  javax.tools

Interface JavaCompiler

  • All Superinterfaces:
    OptionCheckerTool

    public interface JavaCompiler
    extends Tool, OptionChecker
    用于从程序中调用Java编程语言编译器的接口。

    编译器可能在编译期间生成诊断(例如,错误消息)。 如果提供了诊断侦听器,则会将诊断程序提供给侦听器。 如果未提供侦听器,则诊断将以未指定的格式进行格式化,并写入默认输出,即System.err除非另有说明。 即使提供了诊断侦听器,某些诊断可能也不适合Diagnostic ,并将写入默认输出。

    编译器工具具有关联的标准文件管理器,该文件管理器是工具(或内置)本机的文件管理器。 可以通过致电getStandardFileManager获取标准文件管理器。

    只要满足以下方法中详述的任何其他要求,编译器工具就必须与任何文件管理器一起工作。 如果未提供文件管理器,则编译器工具将使用标准文件管理器,例如getStandardFileManager返回的文件管理器。

    实现此接口的实例必须符合The Java™ Language Specification和生成的类文件符合The Java™ Virtual Machine Specification。 这些规范的版本在Tool界面中定义。 此外,支持SourceVersion.RELEASE_6或更高版本的此接口的实例还必须支持annotation processing

    编译器依赖于两种服务: diagnostic listenerfile manager 虽然大多数的类和接口在这个包定义了用于编译器(和工具一般)接口的API DiagnosticListenerJavaFileManagerFileObject ,和JavaFileObject并不意在应用中使用。 相反,这些接口旨在实现并用于为编译器提供定制服务,从而为编译器定义SPI。

    这个包中有许多类和接口,旨在简化SPI的实现以定制编译器的行为:

    StandardJavaFileManager
    实现此接口的每个编译器都提供标准文件管理器,以便在常规files运行 StandardJavaFileManager接口定义了从常规文件创建文件对象的其他方法。

    标准文件管理器有两个用途:

    • 用于自定义编译器如何读取和写入文件的基本构建块
    • 在多个编译任务之间共享

    重用文件管理器可以减少扫描文件系统和读取jar文件的开销。 虽然开销可能没有减少,但标准文件管理器必须使用多个顺序编译,使以下示例成为推荐的编码模式:

      File[] files1 = ... ; // input for first compilation task
           File[] files2 = ... ; // input for second compilation task
    
           JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
           StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    
           Iterable<? extends JavaFileObject> compilationUnits1 =
               fileManager.getJavaFileObjectsFromFiles(Arrays.asList(files1));
           compiler.getTask(null, fileManager, null, null, null, compilationUnits1).call();
    
           Iterable<? extends JavaFileObject> compilationUnits2 =
               fileManager.getJavaFileObjects(files2); // use alternative method
           // reuse the same file manager to allow caching of jar files
           compiler.getTask(null, fileManager, null, null, null, compilationUnits2).call();
    
           fileManager.close(); 
    DiagnosticCollector
    用于收集列表中的诊断信息,例如:
      Iterable<? extends JavaFileObject> compilationUnits = ...;
           JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
           DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
           StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
           compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits).call();
    
           for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics())
               System.out.format("Error on line %d in %s%n",
                                 diagnostic.getLineNumber(),
                                 diagnostic.getSource().toUri());
    
           fileManager.close(); 
    ForwardingJavaFileManagerForwardingFileObjectForwardingJavaFileObject
    子类化不能用于覆盖标准文件管理器的行为,因为它是通过在编译器上调用方法而不是通过调用构造函数来创建的。 而应使用转发(或委托)。 这些类可以轻松地将大多数调用转发给给定的文件管理器或文件对象,同时允许自定义行为。 例如,考虑如何将所有调用记录到JavaFileManager.flush()
      final  Logger logger = ...;
           Iterable<? extends JavaFileObject> compilationUnits = ...;
           JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
           StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
           JavaFileManager fileManager = new ForwardingJavaFileManager(stdFileManager) {
               public void flush() throws IOException {
                   logger.entering(StandardJavaFileManager.class.getName(), "flush");
                   super.flush();
                   logger.exiting(StandardJavaFileManager.class.getName(), "flush");
               }
           };
           compiler.getTask(null, fileManager, null, null, null, compilationUnits).call(); 
    SimpleJavaFileObject
    此类提供基本文件对象实现,可用作创建文件对象的构建块。 例如,以下是如何定义表示存储在字符串中的源代码的文件对象:
      /**
            * A file object used to represent source coming from a string.
            */
           public class JavaSourceFromString extends SimpleJavaFileObject {
               /**
                * The source code of this "file".
                */
               final String code;
    
               /**
                * Constructs a new JavaSourceFromString.
                * @param name the name of the compilation unit represented by this file object
                * @param code the source code for the compilation unit represented by this file object
                */
               JavaSourceFromString(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;
               }
           } 
    从以下版本开始:
    1.6
    另请参见:
    DiagnosticListenerDiagnosticJavaFileManager
    • 方法详细信息

      • getTask

        JavaCompiler.CompilationTask getTask​(Writer out,
                                             JavaFileManager fileManager,
                                             DiagnosticListener<? super JavaFileObject> diagnosticListener,
                                             Iterable<String> options,
                                             Iterable<String> classes,
                                             Iterable<? extends JavaFileObject> compilationUnits)
        使用给定的组件和参数为编译任务创建未来。 编译可能没有按照CompilationTask接口中的描述完成。

        如果提供了文件管理器,则它必须能够处理StandardLocation定义的所有位置。

        请注意,注释处理可以处理要编译的源代码的编译单元,使用compilationUnits参数传递,以及类名文件,其名称通过classes参数传递。

        参数
        out - 编译器的附加输出的Writer; 使用System.err如果null
        fileManager - 文件管理器; 如果null使用编译器的标准文件管理器
        diagnosticListener - 诊断监听器; 如果null使用编译器的默认方法报告诊断
        options - 编译器选项, null表示没有选项
        classes - 注释处理要处理的类的名称, null表示没有类名
        compilationUnits - 要编译的编译单元, null表示没有编译单元
        结果
        表示编译的对象
        异常
        RuntimeException - 如果用户提供的组件中发生不可恢复的错误。 cause将是用户代码中的错误。
        IllegalArgumentException - 如果任何选项无效,或者任何给定的编译单元属于 source以外的其他类型
      • getStandardFileManager

        StandardJavaFileManager getStandardFileManager​(DiagnosticListener<? super JavaFileObject> diagnosticListener,
                                                       Locale locale,
                                                       Charset charset)
        返回此工具的标准文件管理器实现的新实例。 文件管理器将使用给定的诊断侦听器来生成任何非致命的诊断程序。 将通过适当的例外发出致命错误信号。

        如果在调用flushclose后访问标准文件管理器,则会自动重新打开它。 标准文件管理器必须可与其他工具一起使用。

        参数
        diagnosticListener - 用于非致命诊断的诊断侦听器; 如果null使用编译器的默认方法报告诊断
        locale - 格式化诊断时要应用的语言环境; null表示default locale
        charset - 用于解码字节的字符集; 如果null使用平台默认值
        结果
        标准文件管理器