一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java動態編譯執行代碼示例

Java動態編譯執行代碼示例

2021-03-09 13:50zlEven Java教程

這篇文章主要介紹了Java動態編譯執行代碼示例,具有一定借鑒價值,需要的朋友可以參考下。

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

一、獲取JavaCompiler

?
1
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

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

二、編譯

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//獲取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);
//執行編譯任務
task.call();

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

三、執行

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//要加載的類名
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);
//創建類實例
Object obj = cls.newInstance();
//方法參數
Object[] params = {...};
//調用方法
Object result = method.invoke(obj, params);

四、完整代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//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;
    }
}

五、測試

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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);
        //執行測試方法
        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);
    }

測試結果

?
1
2
3
4
5
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動態編譯執行代碼示例的全部內容,希望對大家有所幫助。如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

原文鏈接:http://blog.csdn.net/zleven/article/details/54094493

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91国内精品久久久久影院优播 | 国产一精品一av一免费爽爽 | 亚洲国产成人99精品激情在线 | 成人欧美一区二区三区白人 | 久久爽狠狠添AV激情五月 | 色老板视频在线 | 12345国产精品高清在线 | 欧美午夜网站 | 久久精品男人影院 | 天天综合天天综合 | 四虎影视最新 | 日本高清色视频www 日本高清免费观看 | tube8最近日本护士 | 日韩网站在线观看 | 免费国产成人高清视频网站 | 国产精品福利久久2020 | 日本精品久久久久久久久免费 | 窝窝影院午夜色在线视频 | 亚洲日本aⅴ片在线观看香蕉 | 99久久www免费| 精品视频免费 | 青青草原社区 | 桃花岛在线 | 国产成人手机在线 | 亚洲成年人免费网站 | 高清国产精品久久久久 | 亚洲AV 中文字幕 国产 欧美 | 日本mature乱子视频 | 暖暖免费高清完整版观看日本 | 成人影院在线观看 | 色色色色色色网 | 香蕉人人超人人超碰超国产 | 日本黄色高清视频网站 | 美女禁区视频无遮挡免费看 | 精品久久久久久综合网 | 顶级尤物极品女神福利视频 | 欧美做受 | 四虎影视紧急入口地址大全 | 91高清在线视频 | 亚洲精品青青草原avav久久qv | 双性人bbww欧美双性 |