Java是一種先編譯后解釋的語言。Java編譯器將源代碼編譯成Java字節碼,而Java虛擬機則將字節碼解釋成機器語言。
Java的編譯有兩種方式:靜態編譯和動態編譯。
靜態編譯是指在程序運行前,將Java源代碼編譯成字節碼文件,這個過程叫做Java編譯。編譯過程將源代碼轉換成字節碼,然后將字節碼文件存儲到硬盤上。當需要運行程序時,Java虛擬機會加載字節碼文件,并執行其中的代碼。
//示例:Java靜態編譯 public class Test { public static void main(String[] args) { System.out.println("Hello, World!"); } } //編譯 javac Test.java //運行 java Test
動態編譯是指在程序運行時,將Java源代碼編譯成字節碼,然后將字節碼加載到內存中,再執行。
//示例:Java動態編譯 import java.io.*; import javax.tools.*; public class Test { public static void main(String[] args) throws Exception { //設置Java文件 String fileName = "Test.java"; //讀取文件 String source = new String(Files.readAllBytes(Paths.get(fileName))); //準備編譯器 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); //設置編譯任務 DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null); Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromStrings(Arrays.asList(source)); JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits); //執行編譯任務 if (!task.call()) { for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) { System.err.println(diagnostic.getKind() + ": " + diagnostic.getMessage(null)); } } //執行編譯后的代碼 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); Class<?> aClass = classLoader.loadClass("Test"); aClass.getMethod("main", String[].class).invoke(null, (Object) args); } }
兩種編譯方式各有優缺點,具體應該根據需求選擇使用。