最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java動態(tài)編譯執(zhí)行代碼示例

 更新時間:2017年12月21日 14:05:18   作者:zlEven  
這篇文章主要介紹了Java動態(tài)編譯執(zhí)行代碼示例,具有一定借鑒價值,需要的朋友可以參考下。

在某些情況下,我們需要動態(tài)生成java代碼,通過動態(tài)編譯,然后執(zhí)行代碼。JAVAAPI提供了相應的工具(JavaCompiler)來實現動態(tài)編譯。下面我們通過一個簡單的例子介紹,如何通過JavaCompiler實現java代碼動態(tài)編譯。

一、獲取JavaCompiler

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

獲取JDK提供的java編譯器,如果沒有提供編譯器,則返回null;

二、編譯

//獲取java文件管理類
StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);
//獲取java文件對象迭代器
Iterable<? extends JavaFileObject> it = manager.getJavaFileObjects(files);
//設置編譯參數
ArrayList<String> ops = new ArrayList<String>();
ops.add("-Xlint:unchecked");
//設置classpath
ops.add("-classpath");
ops.add(CLASS_PATH);
//獲取編譯任務
JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, ops, null, it);
//執(zhí)行編譯任務
task.call();

當我們要編譯的源代碼中,引用了其他代碼,我們需要將引用代碼路徑設置到-classpath中,否則會編譯失敗。

三、執(zhí)行

//要加載的類名
String className = "xxx.xxx.xxx";
//獲取類加載器
ClassLoader classLoader = XXX.class.getClassLoader();
//加載類
Class<?> cls = classLoader.loadClass(className);

//調用方法名稱
String methodName = "execute";
//方法參數類型數組
Class<?>[] paramCls = {...};
//獲取方法
Method method = cls.getDeclaredMethod(methodName , paramCls);
//創(chuàng)建類實例
Object obj = cls.newInstance();
//方法參數
Object[] params = {...};
//調用方法
Object result = method.invoke(obj, params);

四、完整代碼

//ClassUtil.java
import 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.LogFactory;
public class ClassUtil {
	private static final Log logger = LogFactory.getLog(ClassUtil.class);
	private static JavaCompiler compiler;
	static{
		compiler = ToolProvider.getSystemJavaCompiler();
	}
	/**
   * 獲取java文件路徑
   * @param file
   * @return
   */
	private static String getFilePath(String file){
		int last1 = file.lastIndexOf('/');
		int last2 = file.lastIndexOf('\\');
		return file.substring(0, last1>last2?last1:last2)+File.separatorchar;
	}
	/**
   * 編譯java文件
   * @param ops 編譯參數
   * @param files 編譯文件
   */
	private static void javac(List<String> ops,String... files){
		StandardJavaFileManager manager = null;
		try{
			manager = compiler.getStandardFileManager(null, null, null);
			Iterable<? extends JavaFileObject> it = manager.getJavaFileObjects(files);
			JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, ops, null, it);
			task.call();
			if(logger.isDebugEnabled()){
				for (String file:files)
				          logger.debug("Compile Java File:" + file);
			}
		}
		catch(Exception e){
			logger.error(e);
		}
		finally{
			if(manager!=null){
				try {
					manager.close();
				}
				catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	/**
   * 生成java文件
   * @param file 文件名
   * @param source java代碼
   * @throws Exception
   */
	private static void writeJavaFile(String file,String source)throws Exception{
		if(logger.isDebugEnabled()){
			logger.debug("Write Java Source Code to:"+file);
		}
		BufferedWriter bw = null;
		try{
			File dir = new File(getFilePath(file));
			if(!dir.exists())
			        dir.mkdirs();
			bw = new BufferedWriter(new FileWriter(file));
			bw.write(source);
			bw.flush();
		}
		catch(Exception e){
			throw e;
		}
		finally{
			if(bw!=null){
				bw.close();
			}
		}
	}
	/**
   * 加載類
   * @param name 類名
   * @return
   */
	private static Class<?> load(String name){
		Class<?> cls = null;
		ClassLoader classLoader = null;
		try{
			classLoader = ClassUtil.class.getClassLoader();
			cls = classLoader.loadClass(name);
			if(logger.isDebugEnabled()){
				logger.debug("Load Class["+name+"] by "+classLoader);
			}
		}
		catch(Exception e){
			logger.error(e);
		}
		return cls;
	}
	/**
   * 編譯代碼并加載類
   * @param filePath java代碼路徑
   * @param source java代碼
   * @param clsName 類名
   * @param ops 編譯參數
   * @return
   */
	public static Class<?> loadClass(String filePath,String source,String clsName,List<String> ops){
		try {
			writeJavaFile(CLASS_PATH+filePath,source);
			javac(ops,CLASS_PATH+filePath);
			return load(clsName);
		}
		catch (Exception e) {
			logger.error(e);
		}
		return null;
	}
	/**
   * 調用類方法
   * @param cls 類
   * @param methodName 方法名
   * @param paramsCls 方法參數類型
   * @param params 方法參數
   * @return
   */
	public static Object invoke(Class<?> cls,String methodName,Class<?>[] paramsCls,Object[] params){
		Object result = null;
		try {
			Method method = cls.getDeclaredMethod(methodName, paramsCls);
			Object obj = cls.newInstance();
			result = method.invoke(obj, params);
		}
		catch (Exception e) {
			logger.error(e);
		}
		return result;
	}
}

五、測試

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.append("import java.util.Map;\nimport java.text.DecimalFormat;\n");
		sb.append("public class Sum{\n");
		sb.append("private final DecimalFormat df = new DecimalFormat(\"#.#####\");\n");
		sb.append("public Double calculate(Map<String,Double> data){\n");
		sb.append("double d = (30*data.get(\"f1\") + 20*data.get(\"f2\") + 50*data.get(\"f3\"))/100;\n");
		sb.append("return Double.valueOf(df.format(d));}}\n");
		//設置編譯參數
		ArrayList<String> ops = new ArrayList<String>();
		ops.add("-Xlint:unchecked");
		//編譯代碼,返回class
		Class<?> cls = ClassUtil.loadClass("/com/even/test/Sum.java",sb.toString(),"com.even.test.Sum",ops);
		//準備測試數據
		Map<String,double> data = new HashMap<String,double>();
		data.put("f1", 10.0);
		data.put("f2", 20.0);
		data.put("f3", 30.0);
		//執(zhí)行測試方法
		Object result = ClassUtil.invoke(cls, "calculate", new Class[]{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 - Write Java Source Code to: .../classes//com/even/test/Sum.java
16:12:03.544 DEBUG com.even.tools.ClassUtil - Compile Java File:.../classes//com/even/test/Sum.java
16:12:03.545 DEBUG com.even.tools.ClassUtil - Load Class[com.even.test.Sum] by sun.misc.Launcher$AppClassLoader@73d16e93
16: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.ClassUtilTest - (30*f1+20*f2+50*f3)/100 = 22.0

總結

以上就是本文關于Java動態(tài)編譯執(zhí)行代碼示例的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:

java編程進行動態(tài)編譯加載代碼分享

Java動態(tài)規(guī)劃之編輯距離問題示例代碼

Java中的引用和動態(tài)代理的實現詳解

如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

相關文章

  • 升級springboot中spring框架的版本的實現方法

    升級springboot中spring框架的版本的實現方法

    本文主要介紹了升級springboot中spring框架的版本的實現方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-08-08
  • Spring框架中的@Conditional系列注解詳解

    Spring框架中的@Conditional系列注解詳解

    這篇文章主要介紹了Spring框架中的@Conditional系列注解詳解,我們需要一個類實現Spring提供的Condition接口,它會匹配@Conditional所符合的方法,然后我們可以使用我們在@Conditional注解中定義的類來檢查,需要的朋友可以參考下
    2024-01-01
  • mybatis判斷int是否為空的時候,需要注意的3點

    mybatis判斷int是否為空的時候,需要注意的3點

    這篇文章主要介紹了mybatis判斷int是否為空的時候,需要注意的3點,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring Boot 入門之消息中間件的使用

    Spring Boot 入門之消息中間件的使用

    本篇文章主要介紹了Spring Boot 入門之消息中間件的使用,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • 詳解使用Spring AOP和自定義注解進行參數檢查

    詳解使用Spring AOP和自定義注解進行參數檢查

    本篇文章主要介紹了詳解使用Spring AOP和自定義注解進行參數檢查,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • java反射的作用知識點總結

    java反射的作用知識點總結

    在本篇文章里小編給大家整理的是關于java反射的作用知識點總結,需要的朋友們可以學習下。
    2020-02-02
  • 一個簡單的Python名片管理系統(tǒng)

    一個簡單的Python名片管理系統(tǒng)

    這篇文章主要為大家詳細介紹了一個簡單的Python名片管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • java nio基礎使用示例

    java nio基礎使用示例

    傳統(tǒng)的io技術為阻塞的,java新nio是非阻塞的,注冊一個op_read事件,注冊到selector對象上,當有數據到來時候,selector回通知之前注冊事件的對象,進行read處理,看面我看看它是如何使用的
    2013-11-11
  • 解決feign調用接口不穩(wěn)定的問題

    解決feign調用接口不穩(wěn)定的問題

    這篇文章主要介紹了解決feign調用接口不穩(wěn)定的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 使用SpringSecurity 進行自定義Token校驗

    使用SpringSecurity 進行自定義Token校驗

    這篇文章主要介紹了使用SpringSecurity 進行自定義Token校驗操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評論

芜湖县| 渭南市| 太仓市| 冷水江市| 晋中市| 卢氏县| 平远县| 来宾市| 天水市| 大新县| 兰西县| 手游| 榆社县| 德格县| 贵溪市| 涞源县| 延长县| 柯坪县| 牟定县| 东丰县| 腾冲县| 商都县| 阳泉市| 彭山县| 沧州市| 周口市| 小金县| 清镇市| 崇信县| 临猗县| 岳西县| 慈溪市| 上林县| 巴塘县| 顺平县| 涿州市| 松潘县| 康定县| 义乌市| 威信县| 越西县|