Dans certains cas, nous devons générer du code Java dynamiquement, compiler dynamiquement, puis exécuter le code. JavaAPI fournit des outils correspondants (Javacompiler) pour implémenter la compilation dynamique. Ci-dessous, nous introduisons comment implémenter la compilation dynamique du code Java via Javacompiler.
1. Obtenez Javacompiler
Javacompiler compiler = toolsprovider.getSystemJavacompiler ();
Obtenez le compilateur Java fourni par JDK, et si aucun compilateur n'est fourni, retournez NULL;
2. Compilation
// Obtenez la classe de gestion de fichiers Java StandardJavaFileManager Manager = compiler.getStandardFileManager (null, null, null); // obtient le fichier java iterator iterator iTable <? étend javafileObject> it = manager.getjavafileObjects (fichiers); // définir les paramètres de compilation arrayList <string> ops = new ArrayList <string> (); ops.add ("- xlint: non coché"); // set classpathhops.add ("- classpath"); ops.addd (classe Javacompiler.compilationTask task = compiler.getTask (null, manager, null, ops, null, it); // exécuter la tâche de compilation tâche.call ();Lorsque nous faisons référence à un autre code dans le code source que nous souhaitons compiler, nous devons définir le chemin du code de référence sur -classpath, sinon la compilation échouera.
Iii. Exécution
// le nom de classe à charger string className = "xxx.xxx.xxx"; // Obtenez la classe Class Classloader classloader = xxx.class.getClassLoader (); // Chargez la classe Class <?> CLS = classloader.loadClass (classname); // Appelez le nom de méthode Méthode Méthode = "EXECUTE"; // Paramètre de paramètre de la méthode {...}; // Obtenez la méthode méthode méthode = cls.getDeclaredMethod (méthodyname, paramcls); // créer l'objet d'instance de classe obj = cls.newinstance (); // Method Paramètre Object [] Params = {...}; // Calling Method Object Result = Method.Invoke (obj, params);4. Code complet
//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.javafa javax.tools.standardjavafileManager; import org.apache.commons.logging.log; import org.apache.commons.logging.logfactory; public class classutil {private static Logger = logfactory.getlog (compiler = compiler); Compiler static {compiler = private static javacompiler compiler; static {compleler = compiler = private static javacompiler compiler compiler; static {compiler = compiler = private static Javacompiler Compuler; Compiler = Compiler = Compilé ToLLProvider.getSystemJavacompiler ();} / ** * Obtenez le Path du fichier Java * @param fichier * @return * / private static String getFilepath (file de chaîne) {int last1 = file.lasteIndexof ('/'); int last2 = file.lastiNDExof ('//'); return file.subString (0, Last1> Last2? Last1: Last2) + file.separatorchar;} / ** * Compile Java File * @param ops Compile Paramètres * @param fichiers Fichier * / StandardJavaFaFaFiLemanager (null, null, null, null; nul); itérable <? étend JavaFileObject> it = manager.getjavafileObjects (fichiers); javacompiler.compilationtask task = compiler.gettask (null, manager, null, ops, null, it); task.call (); if (logger.isdebugeNabled ()) {pour (fichier de chaîne: fichiers) logger.Debug ("compile java:" File à chaîne) logger.Debug ("Compile Fichier:" Fichier à chaîne: fichiers) Logger. Fichier);}} catch (exception e) {logger.error (e);} enfin {if (manager! = null) {try {manager.close ();} catch (ioException e) {e.printstackTrace ();}}}}} / ** * générate java file * @param nom de fichier * @param source java code * @throws exception * @param file nom * @param source java code * @throws exception * @param file nom * @param source java code * @throws exception; writeJavaFile (file de chaîne, source de chaîne) lève une exception {if (logger.isdebugeNabled ()) {logger.debug ("Écrire du code source java sur:" + file);} tamponedwriter bw = null; try {file Dire Diret FileWriter (fichier)); bw.write (source); bw.flush ();} catch (exception e) {throw e;} enfin {if (bw! = Null) {bw.close ();}}} / ** * Classe de chargement * @param name name * @return * / Class static de la classue <? null; try {classloader = classutil.class.getClassloadher (); cls = classloader.loadClass (name); if (logger.isdebugeNabled ()) {logger.debug ("LOCK CLASS Classe de chargement * @param filepath Java Code Path * @Param Source Java Code * @Param ClSname Class Nom * @param Ops Compile Paramètres * @return * / public static class <?> LoadClass (String filepath, String Source, String clsName, list <string> ops) {essayez {writeJavaFile (class_path + filepath, source); javac (ops, class_path + filepath); return chargement (clsName);} catch (exception e) {logger.error (e);} return null;} / ** * appelez la méthode de la classe * @param Classe * @param méthode méthode name * @Param Paramscls Mode paramètre paramètre de la méthode * @param Paramscls Paramètre Paramètre) @return * / public static objet invoke (classe <?> CLS, String Methodname, class <?> [] Paramscls, objet [] params) {objet result = null; try {méthode méthode = cls.getDeclaredMethod (méthode. {logger.error (e);} Retour Résultat;}}V.
classe publique classutiltSest {private static final logger = logfactory.getLog (classutilSt.class); public static void main (String args []) {stringBuilder sb = new StringBuilder (); sb.append ("package com.even.test;"); sb.append ("import java.util.map; / nimport; / nimport; java.text.decimalformat; / n "); sb.append (" public class sum {/ n "); sb.append (" private final decimalformat df = new Decimalformat (/"#.#####/") ;/ n "); sb.append (" double calcul (double D = 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 "); // définir les paramètres de compilation ArrayList <string <string> ops = new ArrayList <string> (); ops.add ("- xlint: Unchecked"); // compiler le code et return classclass <?> CLS = classutil.loadClass ("/ com / même / test / sum.java", sb.toString (), "com.even.test.sum", ops); // préparer le test de données de données <sthring, double> data Hashmap <string, double> (); data.put ("f1", 10.0); data.put ("f2", 20.0); data.put ("f3", 30.0); // exécuter la méthode de test résultat objet = classutil.invoke (cls, "calcul", new class [] {map.class}, nouveau objet [] {data}); // logger.debug (données); logger.debug ("(30 * f1 + 20 * f2 + 50 * f3) / 100 =" + résultat);}Résultats des tests
16: 12: 02.860 DEBUG com.even.tools.classutil - Écrivez le code source Java à: ... / classes // com / pair / test / sum.java16: 12: 03.544 debug com.even.tools.classutil - compilation java fichier: ... / classes // com / même / test / sum.java16: 12: 03.545 Débugg 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}16:12:03.547 DEBUG com.even.test.classuiltst - (30 * f1 + 20 * f2 + 50 * f3) / 100 = 22,0Résumer
Ce qui précède est tout au sujet des exemples de compilation dynamique et de code d'exécution Java, j'espère que cela sera utile à tout le monde. Les amis intéressés peuvent continuer à se référer à ce site:
PROGRAMMATION Java Partage de code compilé et chargé dynamiquement
Java Dynamic Programmation Modifier le problème du problème de distance
Explication détaillée de la mise en œuvre des références et de la procuration dynamique en Java
S'il y a des lacunes, veuillez laisser un message pour le signaler. Merci vos amis pour votre soutien pour ce site!