更新時(shí)間:2021-05-26 15:49:52 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1099次
Java編譯器哪個(gè)好?API就是非常不錯(cuò)的,Java編譯器讀取源文件并生成類文件。(將它們組裝到JAR,WAR,EAR和其他軟件包中是另一種工具的責(zé)任。)源文件和類文件不一定是駐留在磁盤,SSD或內(nèi)存驅(qū)動(dòng)器中的真實(shí)操作系統(tǒng)文件。畢竟,當(dāng)涉及到運(yùn)行時(shí)API時(shí),Java通常對(duì)于抽象是很好的,現(xiàn)在就是這種情況。這些文件是一些“抽象”文件,您必須通過(guò)API提供訪問(wèn)這些文件,這些文件可以是磁盤文件,但同時(shí)幾乎可以是任何其他文件。將源代碼保存到磁盤上只是為了讓編譯器在同一進(jìn)程中運(yùn)行以將其讀回并在類文件準(zhǔn)備好后對(duì)其進(jìn)行相同操作,通常會(huì)浪費(fèi)資源。
Java編譯器作為運(yùn)行時(shí)可用的API,要求您提供一些簡(jiǎn)單的API(或您喜歡的SPI)來(lái)訪問(wèn)源代碼并發(fā)送生成的字節(jié)碼。如果我們?cè)趦?nèi)存中有代碼,則可以有以下代碼:
public Class<?> compile(String sourceCode, String canonicalClassName)
throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
List<JavaSourceFromString> sources = new LinkedList<>();
String className = calculateSimpleClassName(canonicalClassName);
sources.add(new JavaSourceFromString(className, sourceCode));
StringWriter sw = new StringWriter();
MemoryJavaFileManager fm = new MemoryJavaFileManager(
compiler.getStandardFileManager(null, null, null));
JavaCompiler.CompilationTask task = compiler.getTask(sw, fm, null,
null, null, sources);
Boolean compilationWasSuccessful = task.call();
if (compilationWasSuccessful) {
ByteClassLoader byteClassLoader = new ByteClassLoader(new URL[0],
classLoader, classesByteArraysMap(fm));
Class<?> klass = byteClassLoader.loadClass(canonicalClassName);
byteClassLoader.close();
return klass;
} else {
compilerErrorOutput = sw.toString();
return null;
}
}
編譯器實(shí)例可通過(guò)ToolProvider并且要?jiǎng)?chuàng)建編譯任務(wù),我們必須調(diào)用getTask()。該代碼通過(guò)字符串編寫器將錯(cuò)誤寫入字符串。文件管理器(fm)是在同一程序包中實(shí)現(xiàn)的,它只是將文件作為字節(jié)數(shù)組存儲(chǔ)在映射中,其中的鍵是“文件名”。這是類加載器稍后在加載類時(shí)將獲取字節(jié)的位置。該代碼未提供任何可診斷的偵聽器(請(qǐng)參見RT中Java編譯器的文檔),編譯器選項(xiàng)或注釋處理器要處理的類。這些都是空值。最后一個(gè)參數(shù)是要編譯的源代碼列表。我們僅在此工具中編譯一個(gè)類,但是由于編譯器API是通用的并且需要可迭代的源,因此我們提供了一個(gè)列表。由于存在另一個(gè)抽象級(jí)別,因此此列表包含JavaSourceFromString。
要開始編譯,必須“調(diào)用”創(chuàng)建的任務(wù),如果編譯成功,則從生成的一個(gè)或多個(gè)字節(jié)數(shù)組中加載類。請(qǐng)注意,如果在我們編譯的頂級(jí)類中有嵌套類或內(nèi)部類,則編譯器將創(chuàng)建幾個(gè)類。這就是為什么即使只編譯一個(gè)源類,我們也必須維護(hù)類的整個(gè)映射,而不是單個(gè)字節(jié)數(shù)組。如果編譯不成功,則錯(cuò)誤輸出將存儲(chǔ)在一個(gè)字段中并可以查詢。
該類的使用非常簡(jiǎn)單,您可以在單元測(cè)試中找到示例:
private String loadJavaSource(String name) throws IOException {
InputStream is = this.getClass().getResourceAsStream(name);
byte[] buf = new byte[3000];
int len = is.read(buf);
is.close();
return new String(buf, 0, len, "utf-8");
}
...
@Test
public void given_PerfectSourceCodeWithSubClasses_when_CallingCompiler_then_ProperClassIsReturned()
throws Exception {
final String source = loadJavaSource("Test3.java");
Compiler compiler = new Compiler();
Class<?> newClass = compiler.compile(source, "com.javax0.jscc.Test3");
Object object = newClass.newInstance();
Method f = newClass.getMethod("method");
int i = (int) f.invoke(object, null);
Assert.assertEquals(1, i);
}
以上就是動(dòng)力節(jié)點(diǎn)小編介紹的"Java編譯器哪個(gè)好",希望對(duì)大家有幫助,如有疑問(wèn),請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為您服務(wù)。
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)