В некоторых случаях нам нужно динамически генерировать код Java, динамически компилировать, а затем выполнить код. Javaapi предоставляет соответствующие инструменты (Javacompiler) для реализации динамического компиляции. Ниже мы представляем, как реализовать динамическую компиляцию кода Java через javacompiler.
1. Получите Javacompiler
Javacompiler Compiler = ToolProvider.getSystemjavacompiler ();
Получите Java Compiler, предоставленную JDK, и если компилятор не предоставлен, возвращайте NULL;
2. Компиляция
// Получить Java File Management Class StandardJavafileManager Manager = compiler.getStandardFileManager (null, null, null); // Получить итератор файла Java итератор <? extends javafileobject> it = Manager.getJavafileObjects (файлы); // Установить параметры компиляции ArrayList <string> Ops = new ArrayList <String> (); Ops.Add ("-xlint: unchecked"); // set classpathops.add ("-classpath"); Javacompiler.compilationtask task = compiler.gettask (null, manager, null, ops, null, it); // execute task task adsoge.call ();Когда мы ссылаемся на другой код в исходном коде, который мы хотим скомпилировать, нам необходимо установить путь контрольного кода на -classpath, в противном случае компиляция не удастся.
Iii. Исполнение
// Имя класса для загрузки String classname = "xxx.xxx.xxx"; // Получить класс ClassLoader ClassLoader = xxx.class.getClassLoader (); // Загрузить класс класса <?> Cls = classloader.loadclass (classname); // вызывающий метод метода methodname = "execute”; {...}; // Получить метод метода метод = cls.getDeclaredMethod (methodname, paramcls); // Создать объект экземпляра класса obj = cls.newinstance (); // method parameter object [] params = {...}; // cl4. Полный код
//Classutil.javaimport java.io.filewriter; import java.io.bufferedwriter; импорт java.io.file; импорт java.io.ioexception; импорт java.util.arraylist; import javax.tools.javacompiler; импорт javax.tools.toolpravider; impormavaviejoys. javax.tools.standardjavafilemanager; import org.apache.commons.logging.log; import org.apache.commons.logging.logfactory; public class classutil {private static final logger = logfactory.getlog (classutil.class); private static javacompiler compiler; static {compiller. ToolProvider.getSystemJavAcompiler ();}/** * Получить путь к файлу Java * @param file * @return */private static String getFilePath (String file) {int last1 = file.lastIndexof ('/'); int last2 = file.lastIndexof ('//'); Last1> Last2? Last1: Last2)+file.separatorChar;}/*** Compile Java File* @param ops параметры компиляции* @param files compile file*/private static void javac (list <string> ops, string ... files) {standarjavafilemanager = null; null; {Manager = Compiler.getstandArdArder (null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null. null); итерабильный <? Extends JavafileObject> it = Manager.getJavafileObjects (файлы); JavAcompiler.compilationTask task = compiler.getTask (null, Manager, Null, Ops, nul 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) throws exection {if (logger.isdebugenabled ()) {logger.debug ("write java -исходный код по адресу:"+file);} bufferedwriter bw = null; try {file dir = new file (getFilepath (file); if (! dir.exists ()) dir FileWriter (file)); BW.Write (Source); BW.Flush ();} Catch (Exception e) {Throw e;} наконец {if (bw! = Null) {bw.close ();}}}/*** Загрузка класса* @param name* @return*/private static class <?> Load (string name) {? null; try {classloader = classutil.class.getClassloader (); cls = classloader.loadclass (name); if (logger.isdebugenabled ()) {logger.debug ("class class ["+name+"] от"+classloader);}} catch (exception e) {logger.error (e); aterm/atmer/}/}/atrail; Загрузите класс* @param filepath java code path* @param source java code* @param clsname class name* @param ops parameters* @return*/public static class <?> loadclas {writejavafile (class_path+filepath, source); javac (ops, class_path+filepath); return load (clsname);} catch (exection e) {logger.error (e);} return null;}/***** @return */public Static Object invoke (class <?> Cls, String Methodname, Class <?> [] paramscls, Object [] params) {object result = null; try {method method = cls.getdeclaredMethod (methodname, paramscls); объект obj = cls.newinStance (); Result = method (obj); {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 ("/nimport.test; java.text.decimalformat;/n "); sb.append (" открытый класс sum {/n "); sb.append (" private final decimalformat df = new Decimalformat (/"#.#####/") ;/ n "); SB.Append (" public double Deculate (Map <String> Data) {/n "); (30*data.get (/"f1/") + 20*data.get (/"f2/") + 50*data.get (/"f3/"))/100;/n "); sb.append (" return double.valueof (df.format (d);}}/n "); // set parameters parameters arrakeList <строка> ops = op = op = ops = ops = ops = ops = ops = ops = ops = ops = ops = ops = ops = ops = ops = new. ArrayList <string> ();; Ops.Add ("-xlint: unchecked"); // Скомпилируйте код и возврат класса класса Hashmap <string, double> ();; data.put ("f1", 10.0); data.put ("f2", 20.0); data.put ("f3", 30.0); // выполнять результат объекта метода тестирования = classutil.invoke (cls, "Рассчитайте", новый класс [] {map.class}, new object [] {data}; logger.debug (data); logger.debug ("(30*f1+20*f2+50*f3)/100 ="+result);}Результаты теста
16: 12: 02.860 Debug com.even.tools.classutil - Напишите исходный код Java: .../class // com/wors/test/sum.java16: 12: 03.544 Debug com.even.tools.classutil - Compile java файл: ... // com/cest/sum.java16: 12: 03. com.even.tools.classutil - класс нагрузки [com.ven.test.sum] от sun.misc.launcher $ Appclassloader@73d16e9316: 12: 03.547 Debug com.even.test.classutiltest com.even.test.classutestest - (30*f1+20*f2+50*f3)/100 = 22,0
Суммировать
Выше приведено в примерах кода динамического компиляции и кода Java, я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на этот сайт:
Программирование Java Динамически скомпилировано и загружается обмен кодом
Java Dynamic Programming Редактирование
Подробное объяснение реализации ссылок и динамического прокси на Java
Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!