日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java编译器API——使用编译工具

發布時間:2023/12/3 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java编译器API——使用编译工具 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【0】README

0.1)以下內容轉自:?http://suntips.iteye.com/blog/69002

0.2)for basic java compiler API, please visit ?http://blog.csdn.net/pacosonswjtu/article/details/50718494


1)當你需要更好的處理這些結果時,你可以使用第二種方法來訪問編譯器.?

更特別的是,這第二種方式允許開發者將編譯輸出結果用一種更有意義的方式表現出來,而不是簡單的那種送往stdeer的錯誤文本. 利用?StandardJavaFileManager?類我們有這種更好的途徑使用編譯器. 這個文件管理器提供了一種方式,用來處理普通文件的輸入輸出操作. 它同時利用?DiagnosticListener?實例來報告調試信息. 你需要使用的?DiagnosticCollector?類其實是監聽器的一種實現.

2)在搞清楚你需要編譯什么之前,你需要一個文件管理器. 生成一個管理器基本上需要兩步:??創建一個DiagnosticCollector?和 使用?JavaCompiler?的?getStandardFileManager()?方法獲得一個文件管理器. 把DiagnosticListener?對象傳入?getStandardFileManager()?方法中. 這個監聽器可以報告一些非致命的問題,到后來你可以選擇性的通過把它傳入?getTask()?方法來和編譯器共享.?

DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, aLocale, aCharset);

3)你也可以往這個調用里傳入一個 null 值的診斷器,但這樣也就等于用以前的編譯器方法了.

3.1)在詳細查看?StandardJavaFileManager?之前 ,編譯過程涉及到?JavaCompiler?的一個方法叫做?getTask()?. 它有六個參數,返回一個叫做?CompilationTask??內部類的實例:?

JavaCompiler.CompilationTask getTask( Writer out, JavaFileManager fileManager, DiagnosticListener<? super JavaFileObject> diagnosticListener, Iterable<String> options, Iterable<String> classes, Iterable<? extends JavaFileObject> compilationUnits)

3.2)缺省情況下,大部分它的參數可以是 null.

* out: System.err * fileManager: compiler's standard file manager * diagnosticListener: compiler's default behavior * options: no command-line options to compiler * classes: no class names for annotation processing

3.3)最后一個參數?compilationUnits?卻是不能夠為null ,因為它是你要去編譯的東西. 它把我們又帶回了StandardJavaFileManager?類.注意這個參數類型:?Iterable<??extends?JavaFileObject>?. ?StandardJavaFileManager?有兩個方法返回這樣的結果. 你可以使用一個文件對象的List或者String?對象的List,用它們來表示文件名:??

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

3.4)并不僅僅?List?,實際上,任何一個能夠標識需要編譯的內容的集合的?Iterable?都可以. ?List?出現在這里只是因為它容易生成:?

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

3.5)現在你有了編譯源文件的所有的必要的信息. 從?getTask(?) 返回的?JavaCompiler.CompilationTask??實現了Callable?.接口 這樣,想讓任務開始就去調用call()方法.?

JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, compilationUnits); Boolean success = task.call();

4)如果沒有編譯警告和錯誤,這個call() 方法會編譯所有的?compilationUnits?變量指定的文件,以及有依賴關系的可編譯的文件.?

想要知道是否所有的都成功了,去查看一下返回的?Boolean?值. 只有當所有的編譯單元都執行成功了,這個?call()?方法才返回?Boolean.TRUE??. 一旦有任何錯誤,這個方法就會返回?Boolean.FALSE?.

在展示運行這個例子之前,讓我們添加最后一個東西,DiagnosticListener?,?或者更確切的說,?DiagnosticCollector?.的實現類.把這個監聽器當作getTask()的第三個參數傳遞進去,你就可以在編譯之后進行一些調式信息的查詢了.?

for (Diagnostic diagnostic : diagnostics.getDiagnostics()) { System.console().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)); }

5)在最后,你應該調用管理器的close()?方法.

6)把所有的放在一起,就得到的了下面的程序,讓我們重新編譯Hello(StandardJavaFileManagerTest)類.??

package com.corejava.chapter10_2;import java.io.IOException; import java.nio.charset.Charset; import java.util.Locale; import javax.tools.Diagnostic; import javax.tools.DiagnosticCollector; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider;public class AdvancedJavaCompiler {public static void main(String[] args) throws IOException{JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); // 返回java 編譯器// DiagnosticCollector 是監聽器的一種實現DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>(); // java 文件管理器StandardJavaFileManager manager = compiler.getStandardFileManager(diagnostics, Locale.CHINA, Charset.forName("UTF-8")); /* Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) */// 所要編譯的源文件Iterable<? extends JavaFileObject> compilationUnits = manager.getJavaFileObjects("com/corejava/chapter10_2/StandardJavaFileManagerTest.java");CompilationTask task = compiler.getTask(null, manager, diagnostics, null, null, compilationUnits);// 如果沒有編譯警告和錯誤,這個call() 方法會編譯所有的 compilationUnits 變量指定的文件,以及有依賴關系的可編譯的文件.Boolean suc = task.call();/* 只有當所有的編譯單元都執行成功了,這個 call() 方法才返回 Boolean.TRUE . 一旦有任何錯誤,這個方法就會返回 Boolean.FALSE .* 在展示運行這個例子之前,讓我們添加最后一個東西,DiagnosticListener , 或者更確切的說, DiagnosticCollector .的實現類.* 把這個監聽器當作getTask()的第三個參數傳遞進去,你就可以在編譯之后進行一些調式信息的查詢了. */for(Diagnostic diagnostic : diagnostics.getDiagnostics()){System.console().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));}manager.close();System.out.println("success : " + suc);} }


7)然而,如果你把?println??方法改成書寫錯誤的?pritnln?方法,當你運行時你會得到下面的信息:?

E:\bench-cluster\cloud-data-preprocess\CoreJavaAdvanced\src>java com.corejava.chapter10_2.AdvancedJa vaCompiler Code: compiler.err.cant.resolve.location.args Kind: ERROR Position: 139 Start Position: 129 End Position: 147 Source: RegularFileObject[com\corejava\chapter10_2\StandardJavaFileManagerTest.java] Message: 找不到符號 符號: 方法 printnl(java.lang.String) 位置: 類型為java.io.PrintStream的變量 out success : false


Attention) for source code about instances above, please visit??https://github.com/pacosonTang/core-java-volume/tree/master/coreJavaAdvanced/chapter10/10_2

使用Compiler API,你可以實現比在這篇簡要的提示介紹的更多的事情. 例如,你可以控制輸入輸出的目錄或者在集成編譯器里高亮一些編譯錯誤. 現在,向 Java Compiler API表示感謝,你可以使用標準API了. For more information on the Java Compiler API and JSR 199,?see the JSR 199 specification.

總結

以上是生活随笔為你收集整理的java编译器API——使用编译工具的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。