日本免费精品_最新日韩一区_亚洲视频一区在线_a在线视频观看_天天射夜夜骑_粉嫩av一区二区三区_欧美中日韩免费视频_综合图区欧美_国内精品美女在线观看_午夜精品久久久久久久男人的天堂

首頁 > 開發 > Java > 正文

SE6調用Java編譯器的兩種方法

2023-06-10 12:43:23
字體:
來源:轉載
供稿:網友

在很多Java應用中需要在程序中調用Java編譯器來編譯和運行。但在早期的版本中(Java SE5及以前版本)中只能通過tools.jar中的com.sun.tools.javac包來調用Java編譯器,但由于tools.jar不是標準的Java庫,在使用時必須要設置這個jar的路徑。而在Java SE6中為我們提供了標準的包來操作Java編譯器,這就是javax.tools包。使用這個包,我們可以不用將jar文件路徑添加到classpath中了。

 一、使用JavaCompiler接口來編譯Java源程序

使用Java API來編譯Java源程序有很多方法,現在讓我們來看一種最簡單的方法,通過JavaCompiler進行編譯。

我們可以通過ToolProvider類的靜態方法getSystemJavaCompiler來得到一個JavaCompiler接口的實例。

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

JavaCompiler中最核心的方法是run。通過這個方法可以編譯java源程序。這個方法有3個固定參數和1個可變參數(可變參數是從Jave SE5開始提供的一個新的參數類型,用type… argu表示)。前3個參數分別用來為java編譯器提供參數、得到Java編譯器的輸出信息以及接收編譯器的錯誤信息,后面的可變參數可以傳入一個或多個Java源程序文件。如果run編譯成功,返回0。

int run(InputStream in, OutputStream out, OutputStream err, String... arguments)

如果前3個參數傳入的是null,那么run方法將以標準的輸入、輸出代替,即System.in、System.out和System.err。如果我們要編譯一個test.java文件,并將使用標準輸入輸出,run的使用方法如下:

int results = tool.run(null, null, null, "test.java");

下面是使用JavaCompiler的完整代碼:

import java.io.*;
  import javax.tools.*;
  public class test_compilerapi
  {
   public static void main(String args[]) throws IOException
   {
   JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
   int results = compiler.run(null, null, null, "test.java");
   System.out.println((results == 0)?"編譯成功":"編譯失敗");
   // 在程序中運行test
   Runtime run = Runtime.getRuntime();
   Process p = run.exec("java test");
   BufferedInputStream in = new BufferedInputStream(p.getInputStream());
   BufferedReader br = new BufferedReader(new InputStreamReader(in));
   String s;
   while ((s = br.readLine()) != null)
   System.out.println(s);
   }
  }
  public class test
  {
   public static void main(String[] args) throws Exception
   {
   System.out.println("JavaCompiler測試成功!");
   }
  }

編譯成功的輸出結果:

編譯成功
  JavaCompiler測試成功
  編譯失敗的輸出結果:
  test.java:9: 找不到符號
  符號: 方法 printlnln(java.lang.String)
  位置: 類 java.io.PrintStream
  System.out.printlnln("JavaCompiler測試成功!");
  ^
  1 錯誤
  編譯失敗

二、使用StandardJavaFileManager編譯Java源程序

在第一部分我們討論調用java編譯器的最容易的方法。這種方法可以很好地工作,但它確不能更有效地得到我們所需要的信息,如標準的輸入、輸出信息。而在Java SE6中最好的方法是使用StandardJavaFileManager類。這個類可以很好地控制輸入、輸出,并且可以通過DiagnosticListener得到診斷信息,而DiagnosticCollector類就是listener的實現。

使用StandardJavaFileManager需要兩步。首先建立一個DiagnosticCollector實例以及通過JavaCompiler的getStandardFileManager()方法得到一個StandardFileManager對象。最后通過CompilationTask中的call方法編譯源程序。

在使用這種方法調用Java編譯時最復雜的方法就是getTask,下面讓我們討論一下getTask方法。這個方法有如下所示的6個參數。

getTask(Writer out,JavaFileManager fileManager,
  DiagnosticListener diagnosticListener,
  Iterable options,
  Iterable classes,
  Iterable compilationUnits)

這些參數大多數都可為null。它們的含義所下。

·out::用于輸出錯誤的流,默認是System.err。
  ·fileManager::標準的文件管理。
  ·diagnosticListener: 編譯器的默認行為。
  ·options: 編譯器的選項
  ·classes:參與編譯的class。

最后一個參數compilationUnits不能為null,因為這個對象保存了你想編譯的Java文件。

在使用完getTask后,需要通過StandardJavaFileManager的getJavaFileObjectsFromFiles或getJavaFileObjectsFromStrings方法得到compilationUnits對象。調用這兩個方法的方式如下:

Iterable getJavaFileObjectsFromFiles(
  Iterable files)
  Iterable getJavaFileObjectsFromStrings(
  Iterable names)
  String[] filenames = …;
  Iterable 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 diagnostics = new DiagnosticCollector();
   StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
   // 建立用于保存被編譯文件名的對象
   // 每個文件被保存在一個從JavaFileObject繼承的類中
   Iterable 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 options = Arrays.asList("-d", "d://");
  JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager,
  diagnostics, options, null, compilationUnits);

在上面的例子中options處的參數為null,而要傳遞編譯器的參數,就需要將options傳入。

有時我們編譯一個Java源程序文件,而這個源程序文件需要另幾個Java文件,而這些Java文件又在另外一個目錄,那么這就需要為編譯器指定這些文件所在的目錄。

Iterable options = Arrays.asList("-sourcepath", "d://src");

上面的代碼指定的被編譯Java文件所依賴的源文件所在的目錄。

三、從內存中編譯

JavaCompiler不僅可以編譯硬盤上的Java文件,而且還可以編譯內存中的Java代碼,然后使用reflection來運行它們。我們可以編寫一個JavaSourceFromString類,通過這個類可以輸入Java源代碼。一但建立這個對象,你可以向其中輸入任意的Java代碼,然后編譯和運行,而且無需向硬盤上寫.class文件。

import java.lang.reflect.*;
  import java.io.*;
  import javax.tools.*;
  import javax.tools.JavaCompiler.CompilationTask;
  import java.util.*;
  import java.net.*;
  public class test_compilerapi
  {
   private static void compilerJava() throws Exception
   {
   JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
   DiagnosticCollector diagnostics = new DiagnosticCollector();
   // 定義一個StringWriter類,用于寫Java程序
   StringWriter writer = new StringWriter();
   PrintWriter out = new PrintWriter(writer);
   // 開始寫Java程序
   out.println("public class HelloWorld {");
   out.println(" public static void main(String args[]) {");
   out.println(" System.out.println(/"Hello, World/");");
   out.println(" }");
   out.println("}");
   out.close();
   //為這段代碼取個名子:HelloWorld,以便以后使用reflection調用
   JavaFileObject file = new JavaSourceFromString("HelloWorld", writer.toString());
   Iterable compilationUnits = Arrays.asList(file);
   JavaCompiler.CompilationTask task = compiler.getTask(null, null,
   diagnostics, null, null, compilationUnits);
   boolean success = task.call();
   System.out.println("Success: " + success);
   // 如果成功,通過reflection執行這段Java程序
   if (success)
   {
   System.out.println("-----輸出-----");
   Class.forName("HelloWorld").getDeclaredMethod("main", new Class[]
   { String[].class }).invoke(null, new Object[]
   { null });
   System.out.println("-----輸出 -----");
   }
   }
   public static void main(String args[]) throws Exception
   {
   compilerJava();
   }
   }
   // 用于傳遞源程序的JavaSourceFromString類
   class JavaSourceFromString extends SimpleJavaFileObject
   {
   final String code;
   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;
   }
   }

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
国产欧美日韩精品高清二区综合区 | 中文字幕2020第一页| 黄色在线资源| 日韩精品视频在线免费观看 | 精品国产31久久久久久| 婷婷中文字幕一区| 色综合久久六月婷婷中文字幕| 中文字幕日韩欧美在线| 中文字幕综合在线| 亚洲丝袜一区| 欧美日韩国产高清视频| 日韩精品在线免费播放| 日韩一级中文字幕| 69堂精品视频在线播放| 最新日韩中文字幕| 日韩精品福利一区二区三区| 丰满少妇一区| 精品免费久久久| 久草视频在线看| 久久精品日韩无码| 在线视频日韩欧美| 91久久精品视频| 日韩中文字幕亚洲| 日韩av一区二区在线| 欧美日韩国产在线| av丝袜在线| 欧美日韩人人澡狠狠躁视频| 日韩激情一区| 91久久久精品国产| 色99中文字幕| 日韩亚洲一区在线| 国产三级第一页| 欧美日韩亚洲不卡| 精品国产31久久久久久| 91精品国产综合久久香蕉最新版 | 欧美日韩国产在线观看| 日韩欧美一二三区| 精品日韩视频在线观看| 91精品高清| 日韩视频一区二区在线观看| 久久夜色精品国产欧美乱极品| 日韩在线一区二区| 日本不卡一区在线| 国产三级视频网站| 久久蜜桃一区二区| 在线欧美日韩国产| 一区二区精品| 日韩高清不卡| 国产区日韩欧美| 欧美三级在线看| 亚洲a一级视频| 91精品在线观看国产| 一区二区三区在线免费| 国产欧美日韩中文久久| 蜜桃久久av一区| 美女尤物久久精品| av亚洲免费| 日韩视频免费直播| 国产天堂素人系列在线视频| 日韩欧美综合在线| 国产在线观看黄色| 免费在线亚洲| 国产成人精品亚洲| 日韩在线观看视频一区| 欧美国产一级片| 国产三级在线| 亚洲免费观看视频| 欧美日韩在线观看成人| 亚洲一区不卡在线| 成人精品国产福利| 999精品网| 视频一区三区| 中文字幕视频一区二区三区久| 一区二区三区高清在线| 精品久久蜜桃| 欧美日韩国产在线| 亚洲第一中文字幕| 日韩欧美在线不卡| 精品一二三区视频| 日韩精品手机在线| 国产福利久久久| 人妻一区二区三区免费| 91久久精品国产91性色69| 亚洲人成欧美中文字幕| 国产欧美日韩综合精品| 国产免费播放一区二区| 久久99久久久久久久噜噜| 中文字幕人成乱码在线观看| 激情婷婷亚洲| 91极品视频在线观看| 色综合久久六月婷婷中文字幕| 欧美一级免费在线观看| 国产羞羞视频在线播放| 国产欧美自拍一区| 欧美日本精品在线| 国产欧美日韩第一页| 久久99久久久欧美国产| 日韩欧美三级| 日韩中文字幕精品视频| 被陌生人带去卫生间啪到腿软| 亚洲va中文字幕| 日韩视频专区| 欧美久久久网站| 一区二区三区在线免费| 九九在线精品| www.三级.com| 国产123在线| 精品在线一区二区三区| 91精品国产综合久久精品app| 午夜国产欧美理论在线播放| 亚洲高清在线免费| 精品久久香蕉国产线看观看gif| 婷婷精品进入| 日韩精品在线第一页| 久久av免费| 亚洲综合视频一区| 亚洲永久字幕| 欧美日韩三级在线| 午夜一区二区三区视频| 日韩国产成人| 精品国产999| 尤物av一区二区| 一区二区三区高清在线| 国产三级中文字幕| 亚洲免费观看视频| 日韩欧美999| av一卡二卡| 日韩中文在线字幕| 精品久久在线观看| 日韩国产亚洲欧美| 精品国产999| 在线黄色国产电影| 在线视频不卡国产V| 日韩精品在线观| 日韩在线中文| wwwwww在线观看| 国产高清在线视频| 日韩精品在线视频观看| 精品国产欧美日韩不卡在线观看| 久久中文免费视频| 一区三区二区视频| 欧美日韩中文国产| 国产乱国产乱300精品| 国产不卡一区| 国产高清一区| 欧美日韩国产不卡在线看| 国产久卡久卡久卡久卡视频精品| 国产一区在线观看视频| 欧美日韩在线播放视频| 成人无遮挡免费网站视频在线观看| 在线视频你懂得一区| 正在播放日韩精品| 欧美日韩在线播放一区| 欧美熟妇乱码在线一区| 国产欧美日韩中文| 日韩在线中文字幕| 一区三区二区视频| 欧美成人一区二区| 91精品国产免费久久综合| 在线观看免费国产成人软件| 91精品国产91久久久久青草| 日韩一级在线免费观看| 日韩精品在线视频| 日韩欧美三级| 精品成a人在线观看| 国产区视频在线观看| 日韩久久精品成人| 日韩欧美亚洲视频| 亚洲乱码中文字幕| 中文字幕在线播放一区| 久久久久久久久99精品| 亚洲丝袜一区| 亚洲深夜福利| 国产啊啊啊视频在线观看| 日韩不卡av| 亚洲男人在线| 日韩中文字幕视频网| 一区视频在线播放| 国产日韩电影| 1区2区3区在线视频| 91久久久久久久久| 欧美不卡一二三| 久久99久久久欧美国产| 欧美中文字幕第一页| 精品久久九九| 日本国产在线视频| 国产福利在线导航| 国产成免费视频| 国产不卡一区二区在线观看| 亚洲热在线观看| av一卡二卡| 欧美日韩夫妻久久| 欧美日韩国产大片| 欧美日韩亚洲第一| 91欧美日韩| 在线观看免费国产成人软件| 国产福利在线看| 国产激情在线观看| 日韩三级免费观看| 国产欧美日韩亚洲| 日韩www在线| 欧美一级免费在线观看| 欧美亚洲视频在线看网址| www.久久草| 精品一二三四| 日韩在线视频一区| 日韩午夜中文字幕| 国产一区 二区 三区一级| 欧美日韩视频免费看| 亚洲精华国产欧美| 亚洲中文字幕一区| 欧美另类久久久品| 国产在线不卡一区| 日韩欧美在线中文字幕| 欧美日韩一级黄| 日本中文字幕在线观看| 激情久久99| 91xxx在线观看| 亚洲福利在线视频| 国产亚洲视频中文字幕视频| 91精品在线免费观看| 欧美日韩性视频一区二区三区 | 国产裸舞福利在线视频合集| 国产一区三区三区| 免费国产h视频在线观看86| 国产视频97| 一级特黄大欧美久久久| 亚洲国内精品视频| 国产三级在线| 91精品国产91久久| 欧美日韩精品综合| 中文字幕亚洲乱码| 国产黄色小视频| 日韩在线视频一区二区三区| 亚洲欧洲综合另类| 日韩av不卡在线观看| 成人一区二区不卡免费| 欧美中文字幕视频在线观看| 国产成免费视频| 成人欧美亚洲| 国产一二三精品| 日韩国产一区久久| 国产香蕉免费精品视频| 二区三区中文字幕| 欧美日韩高清不卡| 日韩欧美国产片| 日韩精品视频在线观看视频| 91精品国产综合久久香蕉最新版| 中文字幕在线高清| 精品免费视频| 久久99精品久久久久久青青日本| 国产伦精品免费视频| 精品在线网站观看| 国产日韩在线视频| 三级精品视频| 91精品国产综合久久香蕉最新版| 日韩欧美国产综合| 国产色综合网| 欧美日韩亚洲国内综合网俺| 欧美一级久久久久久久久大| 99精品一级欧美片免费播放| 在线免费91| 日韩你懂的电影在线观看| 欧美二三四区| 久久精品在线免费观看| 日韩中文字幕亚洲| 国产成人va亚洲电影| 日韩一级中文字幕| 九七久久人人| 亚洲欧美中文在线视频| 久久久精品国产99久久精品芒果| 一本久久a久久精品亚洲| 国产伦精品免费视频| 天天摸日日摸狠狠添| 国产一二三区精品视频| 国产绿帽一区二区三区| 99色在线视频| 99精品视频99| 99精品在线播放| 国产婷婷色一区二区三区在线| 精品网站999| 国产永久在线观看| 国产区高清在线| 欧美一级欧美三级在线观看| 国产啊啊啊视频在线观看| 免费在线视频一区二区| 欧美日韩国产91| 欧美日韩午夜在线| 欧美日韩国产成人| av一卡二卡| 日韩三级一区| 久久久精品日韩| 精品一区二区在线观看视频| 中文在线中文字幕| 久久久久久久久综合| 亚洲免费婷婷| 91久久久精品国产| 欧美三级日韩三级| 一区视频在线播放| 国产成人精品免费网站| 天天综合天天综合| 欧美在线视频一区二区| 91蜜桃在线视频| 日本亚洲视频在线| 国产欧美亚洲一区| 国产乱国产乱300精品| 免费高清视频日韩| 欧美日韩国产一二三| 欧美日韩精品区| 91精品国产综合久久久久久| 精品久久久视频| 亚洲成av人片一区二区密柚| 日韩av一区二| 日韩中文字幕视频在线| 亚洲第一视频| 99久热re在线精彩视频| aaa欧美日韩| 在线不卡日本| 亚洲久草视频| 91精品国产综合久久香蕉的特点| 欧美中文字幕在线| 亚洲综合日韩中文字幕v在线| av免费观看国产| 国产激情在线播放| wwwwww在线观看| 精品乱子伦一区二区| 欧美日韩精品电影| 日韩午夜中文字幕| 精品不卡一区二区| 国内精品露脸在线视频播放| a天堂在线资源| 国产黄色一区| 视频一区三区| 一级一片免费视频| 亚洲一卡二卡在线观看| 黄色片免费看| 日韩在线欧美| 中文字幕在线国产| 欧美久久一二三四区| 日韩av在线中文字幕| 日韩欧美中文字幕在线观看| 一区二区日韩免费看| 不卡专区在线| 国产日韩1区| 亚洲欧美伊人| 精品国产网站在线观看| 国产一卡2卡3卡四卡网站| 天堂在线中文资源| 成人禁用看黄a在线| 日韩视频在线观看视频| 视频一区视频二区中文| 免费在线观看国产黄| 在线视频不卡国产V| www.xxxx精品| 午夜精品一区二区三区免费视频| 精品国产乱码久久久久久蜜臀| 欧美日韩成人一区| 香蕉人人精品| 国产高清一级片| 在线日韩欧美| 色一区在线观看| 精品久久香蕉国产线看观看gif| av手机天堂| 精品福利二区三区| 久久久91精品| 91精品国产91| 国产在线高清精品| 欧美日韩久久不卡| 91精品国产手机| 国产在线高潮| 伊人中文字幕在线观看| 国产www在线观看| 97视频在线| 五月天久久比比资源色| 日韩精品免费视频一区二区三区| 91精品婷婷国产综合久久| 国产一区精品| 不卡av免费在线| 久久99精品国产| av免费在线观看网址| av免费在线不卡| 久久99精品国产| 最新中文字幕在线| 国产视频中文字幕| 国产拍揄自揄精品视频麻豆| 亚洲精品中文字幕乱码三区| 欧美日韩国产高清一区| 国产在线一区二区视频| 国产一二三视频| 色综合天天性综合| 免费精品国产自产拍观看| www日韩在线观看| 国产亚洲一级| 久久精品女人| 日韩中文在线视频| 不卡在线视频| 人人做人人澡人人爽欧美| 日本a口亚洲| 亚洲欧洲精品在线| 日韩中文字幕二区|