`
kanpiaoxue
  • 浏览: 1781143 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

java程序内部调用jdk的编译器来编译java类

 
阅读更多

编译java类,一般会用java自带的javac,或者采用其他的编译器。使用javac的时候会比较耗时。其实jdk自身就带有编译器的功能类:javax.tools.JavaCompiler.java。使用它可以在代码中直接编译java类。

它的javadoc写的非常清晰:

 

 

 

nterface to invoke Java™ programming language compilers from programs.

The compiler might generate diagnostics during compilation (for example, error messages). If a diagnostic listener is provided, the diagnostics will be supplied to the listener. If no listener is provided, the diagnostics will be formatted in an unspecified format and written to the default output, which is System.err unless otherwise specified. Even if a diagnostic listener is supplied, some diagnostics might not fit in a Diagnostic and will be written to the default output.

A compiler tool has an associated standard file manager, which is the file manager that is native to the tool (or built-in). The standard file manager can be obtained by calling getStandardFileManager.

A compiler tool must function with any file manager as long as any additional requirements as detailed in the methods below are met. If no file manager is provided, the compiler tool will use a standard file manager such as the one returned by getStandardFileManager.

An instance implementing this interface must conform to The Java™ Language Specification and generate class files conforming to The Java™ Virtual Machine Specification. The versions of these specifications are defined in the Tool interface. Additionally, an instance of this interface supporting SourceVersion.RELEASE_6 or higher must also support annotation processing.

The compiler relies on two services: diagnostic listener and file manager. Although most classes and interfaces in this package defines an API for compilers (and tools in general) the interfaces DiagnosticListener, JavaFileManager, FileObject, and JavaFileObject are not intended to be used in applications. Instead these interfaces are intended to be implemented and used to provide customized services for a compiler and thus defines an SPI for compilers.

There are a number of classes and interfaces in this package which are designed to ease the implementation of the SPI to customize the behavior of a compiler:

StandardJavaFileManager
Every compiler which implements this interface provides a standard file manager for operating on regular files. The StandardJavaFileManager interface defines additional methods for creating file objects from regular files.

The standard file manager serves two purposes:

  • basic building block for customizing how a compiler reads and writes files
  • sharing between multiple compilation tasks

Reusing a file manager can potentially reduce overhead of scanning the file system and reading jar files. Although there might be no reduction in overhead, a standard file manager must work with multiple sequential compilations making the following example a recommended coding pattern:

       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
Used to collect diagnostics in a list, for example:
       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();
ForwardingJavaFileManager, ForwardingFileObject, and ForwardingJavaFileObject
Subclassing is not available for overriding the behavior of a standard file manager as it is created by calling a method on a compiler, not by invoking a constructor. Instead forwarding (or delegation) should be used. These classes makes it easy to forward most calls to a given file manager or file object while allowing customizing behavior. For example, consider how to log all calls to 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
This class provides a basic file object implementation which can be used as building block for creating file objects. For example, here is how to define a file object which represent source code stored in a string:
       /**
        * 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;
           }
       }
Since:
1.6
Author:
Peter von der Ahé
Jonathan Gibbons
See Also:
DiagnosticListener
Diagnostic
JavaFileManager
分享到:
评论

相关推荐

    使用JDK开发Java应用程序

    在编写Java源程序后,需要使用Java编译器编译Java源文件。Java编译器将Java源文件编译成Java字节码文件,扩展名为.class。编译器可以使用javac命令来编译Java源文件。在命令窗口中,使用javac命令编译指定目录下的...

    java程序调用matble

    总结来说,本文详尽地介绍了Java程序如何调用Matlab函数的整个流程,包括必须的软件安装、环境配置、项目创建、函数调用及调试。对于初次尝试该过程的开发者,文章不仅提供了技术指导,还指出了常见问题的解决思路,...

    java编译器

    安装或运行这个编译器exe文件,用户可以更便捷地管理和编译Java项目。 "绿盟 - 首页.url" 文件看起来是一个网站书签,可能指向一个与Java编程或开发者社区相关的网站,比如提供Java编程资源、教程、论坛或技术讨论...

    java的jdk6安装包

    2. 动态代理:JDK6引入了`java.lang.reflect.Proxy`类,允许动态创建代理对象,实现接口方法的调用。 3. 注解(Annotation):增强了代码的元数据功能,可以用于编译时检查、运行时处理等。 4. 自动装箱与拆箱:简化...

    java jdk 1.7官网免安装版本

    - **设置环境变量**:在系统环境变量中配置`JAVA_HOME`指向JDK的安装路径,`PATH`添加`bin`目录,确保能全局调用JDK工具。 - **验证安装**:通过运行`java -version`和`javac -version`命令检查Java和Javac是否...

    dll.rar_Java 生成dll_Java程序转为c#调用时需要的dll包_jdk 生成 dll

    2. **编译Java源代码**:使用JDK的javac命令编译Java源代码,生成.class文件。 3. **使用JNI生成C头文件**:使用JDK的javah工具,根据编译后的Java类生成C头文件,它包含了C函数原型,这些函数将被实现以调用Java的...

    JAVA复习资料

    11. **JDK工具**:`javac.exe` 是Java编译器,用于将Java源代码编译成字节码,答案为 `C`。 12. **public 修饰符**:`public` 修饰的类可以被其他任何类访问,答案为 `A`。 13. **容器型构件**:`JPanel` 是Swing中...

    官网下载java 64位1.8版本JDK

    8. **开发工具**:JDK包含的开发工具如`javac`编译器用于将源代码编译成字节码,`javadoc`生成API文档,`jdb`是简单的调试器,还有`jar`工具用于创建和管理Java档案文件。 9. **兼容性与性能优化**:Java 1.8版本...

    jdk安装Java程序设计实验指导书

    实验步骤还包括设置环境变量,特别是`JAVA_HOME`、`PATH`和`CLASSPATH`,这些环境变量使得在命令行环境下能够顺利调用JDK的工具。`JAVA_HOME`应指向JDK的安装目录,`PATH`需要包含`JAVA_HOME/bin`,而`CLASSPATH`则...

    Java快速编译工具

    优点:本程序不需要用户手动敲击CMD命令,只需在图形界面上用鼠标点击即可方便地编译Java源程序,并可自定义class文件的存储位置。同时,在用户点击编译、运行等按钮时,会自动生成相应的CMD命令并通过对话框显示...

    Java JDK 8 exe安装版(Windows 64位)

    Java JDK 8是Java开发工具包的一个重要版本,主要用于在Windows 64位操作系统上进行Java应用程序的开发、编译和运行。这个压缩包提供的exe安装文件是官方原版,确保了安全性和稳定性,用户只需解压后进行安装,即可...

    如何使用Eclipse编译C,C++,JAVA程序

    总结来说,配置Eclipse进行C,C++,JAVA程序的编译,需要先安装JDK和MinGW,然后下载并设置Eclipse SDK,最后安装CDT插件。完成这些步骤后,你就可以在Eclipse中愉快地进行多语言开发了。Eclipse的强大在于其高度的...

    java JDK1.8版本下载

    Java JDK(Java Development Kit)是Java编程语言的软件开发工具包,它包含了编译、调试、运行Java程序所需的所有工具和库。JDK1.8是Oracle公司发布的Java平台标准版(Java SE)的一个重要版本,它在2014年3月18日...

    Java JDK11.0.22.tar.gz下载(Linux)

    JDK(Java Development Kit)是Java程序员的核心工具,包含了JRE(Java Runtime Environment),编译器,调试器,以及其他用于构建和测试Java应用程序的工具。 1. **Java语言基础**: Java是一种跨平台的、面向对象...

    java-jdk介绍

    Java开发工具主要用于编译Java源代码。它不仅提供了基本的编译能力,还支持代码调试、性能分析等多种功能,帮助开发者更高效地完成软件开发工作。这些工具通常通过命令行方式操作,但也有很多集成开发环境(IDEs)如...

    Java程序设计实验报告

    JDK(Java Development Kit)是开发和运行Java应用程序的基础,包含了编译器、JVM(Java虚拟机)和开发工具。实验要求学生完成JDK的安装,并设置相应的环境变量,确保系统能够找到Java编译器和运行时环境。此外,还...

    Java编译器源代码

    Java编译器,通常被称为Javac,是Java开发工具包(JDK)的重要组成部分,负责将源代码转换为可执行的字节码。在Java编程语言中,编译过程并非像C++或C那样直接生成本地机器代码,而是生成跨平台的中间表示——字节码...

Global site tag (gtag.js) - Google Analytics