Module  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 DiagnosticListenerJavaFileManagerFileObjectJavaFileObject并不意在应用中使用。 相反,这些接口旨在实现并用于为编译器提供定制服务,从而为编译器定义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(); 
    ForwardingJavaFileManagerForwardingFileObject ,并ForwardingJavaFileObject
    子类化不能覆盖标准文件管理器的行为,因为它是通过在编译器上调用方法而不是调用构造函数来创建的。 而应该使用转发(或授权)。 这些类使得很容易将大多数调用转发到给定的文件管理器或文件对象,同时允许自定义行为。 例如,考虑如何将所有调用记录到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 - 编写器用于编译器的附加输出; 使用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使用平台默认
        结果
        标准文件管理器