경우에 따라 Java 코드를 동적으로 생성하고 동적으로 컴파일 한 다음 코드를 실행해야합니다. Javaapi는 동적 컴파일을 구현하기위한 해당 도구 (Javacompiler)를 제공합니다. 아래에서는 JavaCompiler를 통해 Java 코드의 동적 컴파일을 구현하는 방법을 소개합니다.
1. Javacompiler를 얻으십시오
JavaCompiler Compiler = ToolProvider.getSystemjavacompiler ();
JDK에서 제공하는 Java 컴파일러를 가져오고 컴파일러가 제공되지 않으면 NULL을 반환하십시오.
2. 컴파일
// Java 파일 관리 클래스 표준 JavaFileManager Manager = Compiler.getStandardFileManager (NULL, NULL, NULL); // Java 파일 개체 ITERATOR ITERABLE을 가져옵니다. javafileobject> it = manager.getJavafileObjects (files); // 컴파일 매개 변수 설정 arraylist arraylist <string> ops = new arraylist <string> (); ops.add ( "-xlint : unchecked"); // classpathhops.add ( "-classpath"); // classpath); javacompiler.compilationtask task = compiler.getTask (null, manager, null, ops, null, it); // 컴파일 작업 task.call ();
컴파일하려는 소스 코드에서 다른 코드를 참조 할 때는 참조 코드 경로를 -classpath로 설정해야합니다. 그렇지 않으면 컴파일이 실패합니다.
III. 실행
//로드 될 클래스 이름 ClassName = "xxx.xxx.xxx"; // 클래스 로더 클래스 로더 클래스 로더 클래스 로더 = xxx.class.getClassLoader (); // 클래스 클래스 클래스 <?> cls = classLoader.loadClass (className); // methodname = "? {...}; // 메소드 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다 메소드를 가져옵니다. 메소드 메소드를 가져옵니다 메소드를 얻습니다4. 코드를 완료하십시오
//classutil.javaimport java.io.filewriter; import java.io.bufferedwriter; import java.io.file; import java.io.ioexception; import java.util.arraylist; import javax.tools.javaCompiler; import javax.toolprovider; javax.tools.standardjavafilemanager; import org.apache.commons.logging.log; import org.apache.commons.logging.logfactory; public classutil {private static final logger = logfactory.getlog (private static javacompiler compiler; compiler; ToolProvider.getSystemjavacompiler ();}/** * Java 파일 경로 * @param 파일 * @return */private static string getFilePath (String file) {int last1 = file.lastIndexOf ( '/'); int last2 = file.lastIndexof ( '//'); return file.substring last1> last2? last1 : last2)+file.separatorchar;}/*** java 파일을 컴파일* @param ops compile 매개 변수* @param 파일 컴파일 파일*/private static void javac (list <string> ops, string ... 파일) {StandardJavafileManager Manager = NULL; try {manager = compiler.getSpandmemanager (null, null, null, standardfilemange). null); 반복 가능한 <? javafileobject> it = manager.getjavafileobjects (files); javacompiler.compilationtask task = compiler.getTask (null, manager, null, ops, null, it); task.call (); if (logger.isdebugenabled ()) {for (string file : files) + 파일 ( "compile java 파일 :" file);}}catch(Exception e){logger.error(e);} finally{if(manager!=null){try {manager.close();}catch (IOException e) {e.printStackTrace();}}}}/** * Generate java file* @param file file name* @param source java code* @throws Exception */private static void WriteJavaFile (String File, String Source)은 예외를 {if (logger.isdebugenabled ()) {logger.debug ( "+file);} bufferedWriter bw = null; try {file dir = new File (! if (! dir.exists);)); BufferedWriter(new FileWriter(file));bw.write(source);bw.flush();}catch(Exception e){throw e;} finally{if(bw!=null){bw.close();}}}/** * Loading class* @param name Class name* @return */private static Class<?> load(String name){Class<?> cls = null; classloader classloader = null; try {classloader = classutil.class.getclassloader (); cls = classloader.loadclass (name); if (logger.isdebugenabled ()) {logger.debug ( "+classloader (});}}에 의해"로드 클래스 [ "+name+"]; cls;}/*** 컴파일 코드 및로드 클래스* @param filepath java code path* @param 소스 Java 코드* @param clsname 클래스 이름* @param ops compile 매개 변수*/public static class <?> loadclass (문자열 filepath, 문자열 소스, 문자열 clsname, list <string> ops) {try {writeJavafile (class_path+filepath, source); javac (ops, class_path+filepath); return load (clsname);} catch (예외 e) {logger.error (e);}/** *** @param cls class* @param methome method name* @param method method parameter parameter parameter parameter parameter parameter */public static 객체 호출 (class <?> cls, string methodname, class <?> [] paramscls, object [] params) {object result = null; try {method = cls.getDeclaredMethod (methodName, paramscls); Object obj = cls.newInstance (); result = incoder = .invoke (params,}); {logger.error (e);} return result;}}V. 테스트
public classutiltest {private static final logger = logfactory.getLog (classUtiltest.class); public static void main (String args []) {StringBuilder sb = new StringBuilder (); SB.Append ( "패키지 com.eva.test;"); sb.append ( "import java.util.map;/nimport; Java.text.decimalformat;/n "); (30*data.get (/"f1/") + 20*data.get (/"f2/") + 50*data.get (/"f3/"))/100;/n "); sb.append ("return d ArrayList <string> (); ops.add ( "-xlint : unchecked"); // 코드를 컴파일하고 classclass <?> cls = classutil.loadclass ( "/com/evide/test/sum.java", sb.tostring (), "com.even.test.sum", ops); hashmap <string, double> (); data.put ( "f1", 10.0); data.put ( "f2", 20.0); data.put ( "f3", 30.0); // 테스트 메소드 객체 실행 결과 = classutil.invoke (cls, "new class [] {map.class}, new Object [] {data}); logger.debug (data); logger.debug ( "(30*f1+20*f2+50*f3)/100 ="+result);}테스트 결과
16 : 12 : 02.860 디버그 com.even.tools.classutil- java 소스 코드 작성 : .../classe // com/evine/test/sum.java16 : 12 : 03.544 debug com.even.tools.classutil -Compile Java 파일 : .../com/over/sum.java16 : 12 : 03.545 com.even.tools.classutil-로드 클래스 [com.even.test.sum] by sun.misc.launcher$ appclasloader@73d16e9316 : 12 : 03.547 debug com.even.test.classutiltest -{f1 = 10.0, f2 = 20.0, f3 = 30 : 03.547 com.even.test.classutiltest- (30*f1+20*f2+50*f3)/100 = 22.0요약
위의 내용은 Java Dynamic Compilation 및 Execution Code 예제에 관한 것이므로 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구들은이 사이트를 계속 참조 할 수 있습니다.
Java 프로그래밍 동적 컴파일 및로드 된 코드 공유
Java 동적 프로그래밍 편집 거리 문제 예제 코드
Java의 참조 및 동적 프록시 구현에 대한 자세한 설명
단점이 있으면 메시지를 남겨 두십시오. 이 사이트를 지원해 주신 친구들에게 감사드립니다!