場合によっては、Javaコードを動的に生成し、動的にコンパイルしてからコードを実行する必要があります。 Javaapiは、動的コンパイルを実装するための対応するツール(Javacompiler)を提供します。以下に、Javacompilerを介してJavaコードの動的コンパイルを実装する方法を紹介します。
1。Javacompilerを取得します
javacompiler compiler = toolprovider.getSystemJavacompiler();
JDKが提供するJavaコンパイラを取得し、コンパイラが提供されていない場合は、NULLを返します。
2。コンピレーション
// javaファイル管理クラスを取得standardjavafilemanager manager = compiler.getSandardFileManager(null、null、null); // javaファイルオブジェクトiterator iterable <? javafileobject> it = manager.getjavafileobjects(files); //コンピレーションパラメーターArraylist <string> ops = new arraylist <string>(); ops.add( "-xlint:unチェック"); task = compiler.getTask(null、manager、null、ops、null、it); //コンピレーションタスクtask.call();
コンパイルするソースコードの他のコードを参照している場合、参照コードパスを-classpathに設定する必要があります。そうしないと、コンパイルが失敗します。
iii。実行
//ロードされるクラス名classname = "xxx.xxx.xxx"; // class loader classloader classloader = xxx.class.getClassLoader(); //クラスクラス<? {...}; //メソッドメソッドメソッドを取得する方法= cls.getDeclaredMethod(methodname、paramcls); //クラスインスタンスオブジェクトobj = cls.newinstance(); //メソッドパラメーターオブジェクト= {...}; //呼び出しメソッドオブジェクトresults = method.invoke(obj、params);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.tools.ToolProvider;import javax.tools.JavaFileObject;import javax.tools.standardjavafilemanager; Import org.apache.commons.logging.log; import org.apache.commons.logging.logactory; public classutil {private static final logger = logactory.getlog(classutil.class); private javacompiler compiler toolprovider.getSystemJavacompiler();}/** * javaファイルパスを取得 * @param file * @return */private static string getfilepath(int last1 = file.lastindexof( '/'); int last2 = file.lastindexof( '//'); return file.substring( '); last1> last2?last1:last2)+file.separatorchar;}/*** java file* @param opsコンパイルパラメーター* @paramファイルコンパイルファイル*/private static void javac(list <string> ops、string ... files){stardentjavafilemanager manager = null; null); iterable <? javafileobject> it = manager.getjavafileobjects(files); javacompiler.compilationtask task = compiler.gettask(null、manager、null、ops、null、it); task.call(); if(logger.isdebugenabled()){for(for:file:files:file: " + debugファイル) writejavafile(string file、string source)スロー例外{if(logger.isdebugenabled()){ogger.debug( "java source code to"+file);} bufferedwriter bw = null; try {file dir = new file(getFilePath(file)); bufferedwriter(new filewriter(file)); bw.write(source); bw.flush();} catch(expent e;}最後に{if(bw!= null){bw.close();}}}/*** @param name name*/prive class*/private class <<<class < null; classloader classloader = null; try {classloader = classutil.class.getClassLoader(); cls = classloader.loadclass(name); if(logger.isdebugenabled()){logger.debug( "load class ["+name+"] by"+class(e) cls;}/***コードとロードクラス* @param filepath javaコードパス* @param source java code* @param clsnameクラス名* @param opsコンパイルパラメーター* @return*/public static class <? {writejavafile(class_path+filepath、source); javac(ops、class_path+filepath); return load(clsname);} catch(例外e){obger.error(e);} return null;}/*** call class method* @param method* @param parmscls methet* @param pramsclmest pamet */public staticオブジェクトInvoke(class <?> cls、string methodname、class <? {logger.error(e);} return result;}}V.テスト
public class classutiltest {private static final log logger = logfactory.getlog(classutiltest.class); public static void main(string args []){stringbuilder sb = new stringbuilder(); sb.append( "package com.even.test;"); sb.; java.text.decimalformat;/n "); sb.append(" public class sum {/n "); sb.append(" private final decimalformat df = new decimalformat(/"#.####/」 (30*data.get(/"f1/") + 20*data.get(/"f2/") + 50*data.get(/"f3/"))/n ") arrayList <string>(); ops.add( "-xlint:unチェック"); //コードをコンパイルしてClassClass <? hashmap <string、double>(); data.put( "f1"、10.0); data.put( "f2"、20.0); data.put( "f3"、30.0); //テストメソッドオブジェクト結果= classutil.invoke(cls、 "calculate"、new class [] {map.class}、新しいオブジェクト[] logger.debug(data); logger.debug( "(30*f1+20*f2+50*f3)/100 ="+result);}テスト結果
16:12:02.860デバッグcom.even.tools.classutil- Javaソースコードを.../classs // com/even/test/sum.java16:12:03.544 debug com.even.even.tools.classutil -compile java file:.../com // com.even.tools.classutil -load class [com.even.test.sum] by sun.misc.launcher$appclassloader@73d16e9316:12:03.547 debug com.even.test.classutiltest- {f1 = 10.0、f2 = 20.0、f3 = 30.0:12:0347:03.547:03.547 com.even.test.classutiltest-(30*f1+20*f2+50*f3)/100 = 22.0要約します
上記は、Javaのダイナミックコンピレーションと実行コードの例に関するすべてです。すべての人に役立つことを願っています。興味のある友達は引き続きこのサイトを参照できます:
Javaプログラミングは、動的にコンパイルされ、コード共有をロードしました
Javaダイナミックプログラミング編集距離問題の例コード
Javaの参照と動的プロキシの実装の詳細な説明
欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!