ในบางกรณีเราจำเป็นต้องสร้างรหัส Java แบบไดนามิกคอมไพล์แบบไดนามิกจากนั้นเรียกใช้รหัส Javaapi จัดเตรียมเครื่องมือที่สอดคล้องกัน (Javacompiler) เพื่อใช้การรวบรวมแบบไดนามิก ด้านล่างเราแนะนำวิธีการรวบรวมรหัส Java แบบไดนามิกผ่าน Javacompiler
1. รับ javacompiler
Javacompiler Compiler = ToolProvider.getSystemjavacompiler ();
รับคอมไพเลอร์ Java ที่จัดทำโดย JDK และหากไม่มีคอมไพเลอร์ให้คืนค่า NULL;
2. การรวบรวม
// รับคลาสการจัดการไฟล์ Java StandardJavafileManager = Compiler.getStandardFileManager (NULL, NULL, NULL); // รับวัตถุไฟล์ Java Iterator Iterable <? ขยาย JavafileObject> it = manager.getJavafileObjects (ไฟล์); // ตั้งค่าพารามิเตอร์การรวบรวม arraylist <String> ops = arrayList ใหม่ <String> (); ops.add ("-xlint: unchected"); // set classpathhops.add (" javacompiler.compilationTask task = Compiler.getTask (Null, Manager, NULL, OPS, NULL, IT); // ดำเนินการคอมไพล์ Task.CALL ();เมื่อเราอ้างอิงรหัสอื่นในซอร์สโค้ดที่เราต้องการรวบรวมเราจำเป็นต้องตั้งค่าเส้นทางรหัสอ้างอิงเป็น -classPath มิฉะนั้นการรวบรวมจะล้มเหลว
iii. การประหารชีวิต
// ชื่อคลาสที่จะโหลดสตริง className = "xxx.xxx.xxx"; // รับคลาส loader classloader classloader = xxx.class.getClassloader (); // โหลดคลาสคลาส <?> cls = classloader.loadclass {... }; // รับเมธอดวิธี = cls.getDeclaredMethod (methodName, paramcls); // สร้างอินสแตนซ์คลาสวัตถุ obj = cls.newinstance (); // เมธอดพารามิเตอร์วัตถุ [] params = {... };4. รหัสสมบูรณ์
//classutil.javaimport java.io.filewriter; นำเข้า java.io.bufferedwriter; นำเข้า java.io.file; นำเข้า java.io.ioexception; นำเข้า java.util.arraylist; นำเข้า Javax.tools.javacompiler; javax.tools.standardjavafileManager; นำเข้า org.apache.commons.logging.log; นำเข้า org.apache.commons.logging.logfactory; คลาสสาธารณะ Classutil toolprovider.getSystemJavaCompiler ();}/** * รับพา ธ ไฟล์ java * @param ไฟล์ * @return */สตริงคงที่ส่วนตัว getFilepath (ไฟล์สตริง) {int last1 = file.Alastindexof ('/'); int last2 = file.lastindexof last1> last2? last1: last2)+file.Saperatorchar;}/*** คอมไพล์ไฟล์ java* @param ops พารามิเตอร์คอมไพล์* @param ไฟล์คอมไพล์ไฟล์*/โมฆะส่วนตัว javac (รายการ <string> ops, สตริง ... ไฟล์) NULL); iterable <? ขยาย javafileObject> it = manager.getJavafileObjects (ไฟล์); javacompiler.CompilationTask task = Compiler.getTask (null, manager, null, ops, null, it); task.call (); if (logger.isdebugenabled ไฟล์);}} catch (exception e) {logger.error (e);} ในที่สุด {ถ้า (manager! = null) {ลอง {manager.close ();} catch (ioexception e) {e.printstacktrace ();}}}}/** writejavafile (ไฟล์สตริงแหล่งที่มาของสตริง) พ่นข้อยกเว้น {ถ้า (logger.isdebugenabled ()) {logger.debug ("เขียนซอร์สโค้ด Java เป็น:"+ไฟล์);} bufferedWriter bw = null; ลอง {ไฟล์ dir = ไฟล์ใหม่ (getFilepath (ไฟล์)) fileWriter (ไฟล์)); bw.write (แหล่งที่มา); bw.flush ();} catch (ข้อยกเว้น e) {โยน e;} ในที่สุด {ถ้า (bw! = null) {bw.close ();}}}/** classloader = null; ลอง {classloader = classutil.class.getClassLoader (); cls = classloader.loadclass (ชื่อ); if (logger.isdebugenabled ()) {logger.debug ("load class ["+ชื่อ+"] โดย"+classloader); คอมไพล์โค้ดและคลาสโหลด* @param filepath java รหัสพา ธ* @param แหล่งที่มาของรหัส java* @param clsname ชื่อคลาส* @param ops คอมไพล์พารามิเตอร์* @return*/คลาสสแตติกสาธารณะ <?> loadclass {writejavafile (class_path+filepath, แหล่งที่มา); javac (ops, class_path+filepath); return load (clsname);} catch (ข้อยกเว้น e) {logger.error (e);} return null; @return */วัตถุสาธารณะคงที่เรียกใช้ (คลาส <?> cls, สตริงเมธอด, คลาส <?> [] paramscls, วัตถุ [] params) {object result = null; ลอง {วิธีการ = cls.getDeclaredMethod {logger.error (e);} ส่งคืนผลลัพธ์;}}V. ทดสอบ
คลาสสาธารณะ classutiltest {logger log สุดท้ายคงที่ = logfactory.getLog (classutiltest.class); โมฆะคงที่สาธารณะหลัก (String args []) {StringBuilder SB = ใหม่ StringBuilder (); sb.append ("แพ็คเกจ com.even.test;"); sb.append ( java.text.decimalformat;/n "); sb.append (" ผลรวมคลาสสาธารณะ {/n "); sb.append (" ส่วนตัวสุดท้าย decimalformat df = decimalformat ใหม่ (/"#.######/") ;/ n "); sb.append ( (30*data.get (/"f1/") + 20*data.get (/"f2/") + 50*data.get (/"f3/"))/100;/n "); sb.append (" ส่งคืน double.valueof (df.format (d));}}/n "); arraylist <String> (); ops.add ("-xlint: unchected"); // รวบรวมรหัสและส่งคืนคลาสคลาส <?> cls = classutil.loadclass ("/com/even/test/sum.java", sb.toString (), "com.even.test.sum" hashmap <string, double> (); data.put ("f1", 10.0); data.put ("f2", 20.0); data.put ("f3", 30.0); // ดำเนินการทดสอบวิธีการทดสอบวัตถุ = classutil.invoke (cls, "คำนวณ", คลาสใหม่ [] {map.class} logger.debug (data); logger.debug ("(30*f1+20*f2+50*f3)/100 ="+ผลลัพธ์);}ผลการทดสอบ
16: 12: 02.860 debug com.even.tools.classutil - เขียนซอร์สโค้ด Java ไปที่: .../คลาส // com/even/test/sum.java16: 12: 03.544 debug com.even.tools.classutil com.even.tools.classutil - คลาสโหลด [com.even.test.sum] โดย sun.misc.launcher$aplasslader@73d16e9316: 12: 03.547 debug com.even.test.classutiltest - {f1 = 10.0, f2 = 20.0 com.even.test.classutiltest - (30*f1+20*f2+50*f3)/100 = 22.0สรุป
ข้างต้นคือทั้งหมดที่เกี่ยวกับตัวอย่างการรวบรวมและรหัสการดำเนินการของ Java Dynamic ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงเว็บไซต์นี้ต่อไปได้:
การเขียนโปรแกรม Java รวบรวมและโหลดรหัสแบบไดนามิก
Java Dynamic Programming แก้ไขปัญหาระยะทาง
คำอธิบายโดยละเอียดเกี่ยวกับการดำเนินการอ้างอิงและพร็อกซีแบบไดนามิกใน Java
หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น ขอบคุณเพื่อนที่ให้การสนับสนุนเว็บไซต์นี้!