Em alguns casos, precisamos gerar código Java dinamicamente, compilar dinamicamente e executar o código. O Javaapi fornece ferramentas correspondentes (Javacompiler) para implementar a compilação dinâmica. Abaixo, introduzimos como implementar a compilação dinâmica do código Java através do Javacompiler.
1. Obtenha Javacompiler
Javacompiler compilador = ToolProvider.getSystemJavacompiler ();
Obtenha o compilador Java fornecido pelo JDK e, se nenhum compilador for fornecido, retorne nulo;
2. Compilação
// Obtenha a classe Java Gerenciamento de Arquivos StandardJavafilemanager Gerenciador = Compiler.getStandardFilemanager (NULL, NULL, NULL); // Obtenha o iterador de objeto de arquivo java iterable <? estende JavafileObject> it = gerenciador.getJavafileObjects (arquivos); // Defina os parâmetros de compilação ArrayList <String> ops = new ArrayList <String> (); ops.add ("-xlint: não-checked"); // ClassPathP.Ads.add ("-ClassPath"); Javacompiler.compilationTask tarefa = compiler.gettask (null, gerente, null, ops, nulo, it); // executar tarefa de compilação de compilação.call ();Quando estamos referenciando outro código no código -fonte que queremos compilar, precisamos definir o caminho do código de referência para -ClassPath, caso contrário, a compilação falhará.
Iii. Execução
// o nome da classe a ser carregado string className = "xxx.xxx.xxx"; // obtenha a classe ClassLoader classLoader = xxx.class.getclassloader (); // carregar a classe Class <?> Cls = classLoader.loadclass (className); // chamando o nome do método Metodname = " {...}; // Obtenha o método do método do método = cls.getDecLaredMethod (MethodName, Paramcls); // Crie o objeto de instância da classe obj = cls.newInstance (); // Método Parâmetro Objeto [] Params = {...}; // Método de chamando resultado do objeto = Método.invoke (obj, obj, obj, obj, obj, {... ...};4. Código completo
//Classutil.javaimport java.io.filewriter; importar java.io.bufferwriter; importar java.io.file; importar java.io.ioexception; importar java.util.arrayList; importar javax.tool.javacompiler; importação de importool.oLoLiToList; javax.tools.standardjavafilemanager; importar org.apache.commons.logging.log; importar org.apache.commons.logging.logfactory; public class Classutil {private STATATIC Logger = LogFactory.getLog (classutil.class); spotatic spotatic spoTerTer Compiler Compiler. ToolProvider.getSystemJavacompiler ();}/** * Obtenha o caminho do arquivo java * @Param File * @return */String estática privada getFilePath (file string) {int last1 = file.lastIndexOf ('/'); int last2 = file.LastIndexOf ('//'); last1> last2? last1: last2)+file.separatorchar;}/*** compilar o arquivo java* @param ops compilar parâmetros* @param arquivos compilar arquivos*/private estático void javac (list <string> ops, string ... arquivos) {StandardJavaNEManager Manager = null; try {gerenciador> complicador. nulo); iterável <? estende JavafileObject> it = gerenciador.getjavafileObjects (arquivos); javacompiler.compilationTask tarefa = compiler.gettask (null, gerente, nulo, ops, null, it); task.call (); if (logger.isdebuGenabled ()) {para (strac arquivo);}} Catch (Exceção e) {Logger.error (e);} finalmente {if (gerenciador! = null) {try {gerenciador.close ();} catch (ioexception e) {e.printStacktrace ();}}}}/**** gere java file* @filear filev* Filev* Filev* Filev* Filev* Filev* Filev* Filev* Filev* Filev* Filev Filev () @M) writejavafile (arquivo string, fonte de string) lança a exceção {if (logger.isdebugenabled ()) {logger.debug ("escreva o código -fonte java para:"+file);} bufferWriter bw = null; tente {file dir = new File (getFilePath (file); se (! FileWriter (file)); BW.Write (fonte); bw.flush ();} Catch (Exceção e) {throw e;} finalmente {if (bw! = Null) {bw.close ();}}}}/*** **** raten @class name* @return*/private Class <? null; try {classLoader = Classutil.class.getclassLoader (); cls = classloader.loadclass (name); if (logger.isdebugenabled ()) {logger.debug ("carregar classe ["+name+"] por"+classLload);}} Catch (exceção e) {Log. Log. Classe de carregamento* @param filepath java Código caminho* @param fonte java code* @param clsname class name* @param ops parâmetros de compilação* @return*/public static class <? {writejavafile (class_path+filepath, fonte); javac (ops, class_path+filepath); carga de retorno (clsname);} catch (exceção e) {logger.error (e);} retornar o método null;}/** *** */Objeto estático público Invoke (classe <?> CLS, String MethodName, classe <?> [] paramscls, object [] params) {objeto resultado = null; try {método method = cls.getDecLaredMethod (MethodName, paramscls); object obj = cls.NewInstance (); resultado = método.inVOKE {Logger.error (e);} Retorno Result;}}V. teste
classe pública ClassutilTestest {private estático Log Logger = LogFactory.getLog (ClassutilTest.class); public static void main (string args []) {stringbuilder sb = new stringbuilder (); sb.append ("pacote com.even.test; java.text.decimalformat;/n "); sb.append (" public classe sum {/n "); sb.append (" Decimalformat final privado df = novo decimalformat (/&"#.####/")/ n "); (30*data.get (/"f1/") + 20*data.get (/"f2/") + 50*data.get (/"f3/"))/100;/n "); sb.append (" return duplo.valueof (df.format (d));}/n "); ArrayList <String> (); ops.add ("-xlint: desmarcada"); // compilar o código e retornar classe ClassClass <?> CLS = Classutil.loadclass ("/com/par/test/sum.java", sb.tostring (), "com.ven.test.test.sum", ops "; Hashmap <string, double> (); data.put ("f1", 10.0); data.put ("f2", 20.0); data.put ("f3", 30.0); // execute o resultado do método de teste resultado = Classutil.inVoke (cls, "calcular", nova classe [] {map.clats},}, objeto novo [], "calcular", nova classe []; logger.debug (dados); logger.debug ("(30*f1+20*f2+50*f3)/100 ="+resultado);}Resultados do teste
16: 12: 02.860 Debug com.ven.tools.classutil - Escreva o código -fonte java para: .../classes // com/par/test/sum.java16: 12: 03.544 Debug COM.Even.Tools.Classutil - Compile File: ... com.Even.tools.classutil - Carregar classe [com.even.test.sum] por Sun.misc.launcher$AppClassloadler@73d16e9316: 12: 03.547 Debug com.ven.test.classTestest - {{F1 = 10,0, F2 = 20.0, F3, f3. com.Even.Test.ClassutilTest - (30*F1+20*F2+50*F3)/100 = 22,0Resumir
O exposto acima é sobre exemplos de código dinâmico de compilação e execução do Java, espero que seja útil para todos. Amigos interessados podem continuar se referindo a este site:
Programação Java Compartilhamento de código compilado e carregado dinamicamente
Java Dynamic Programming Editar Distância Problema Exemplo Código
Explicação detalhada da implementação de referências e proxy dinâmico em Java
Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio para este site!