- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java动态编译执行代码示例由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
在某些情况下,我们需要动态生成java代码,通过动态编译,然后执行代码。JAVAAPI提供了相应的工具(JavaCompiler)来实现动态编译。下面我们通过一个简单的例子介绍,如何通过JavaCompiler实现java代码动态编译.
1、获取JavaCompiler 。
1
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
获取JDK提供的java编译器,如果没有提供编译器,则返回null; 。
2、编译 。
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中,否则会编译失败.
3、执行 。
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);
|
4、完整代码 。
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;
}
}
|
5、测试 。
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 。
最后此篇关于Java动态编译执行代码示例的文章就讲到这里了,如果你想了解更多关于Java动态编译执行代码示例的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
是否有任何库或框架旨在促进从另一种成熟的编程语言中构建项目? 在 C++、java 等编程语言中指定逻辑、集合和复杂规则非常容易,但在 Makefile 中完成这些事情似乎是一场艰苦的战斗。我还没有深
我有这段代码可以用 clang 编译得很好(即使使用 -Weverything),但是 gcc 会发出错误。 #include #include #include using namespace
我有以下 block 头文件 BKE_mesh.h: /* Connectivity data */ typedef struct IndexNode { struct IndexNode *
我在我的一个项目中遇到了一个奇怪的问题。我的代码库依赖于一个外部库,其中包含一个名为 Dataset 的类. Dataset类私有(private)继承自 std::vector (其中 Sample
当使用 gcc、g++ 或 make 在终端中编译一个小型 C 或 C++ 项目时,我收到以下错误: /tmp/ccG1caGi.o: In function `main': main.c:(.tex
我正在尝试从 CVS 为 Windows 上的 Emacs 23.1.50 编译 CEDET,但在“第 6 步:打开 EDE...”时出现错误:“defvar:作为变量的符号值是无效的:cedet-m
我正在(重新)学习编程,我从 C 开始。我的 IDE(如果我可以这么说)是 Windows7 上的 cygwin(32 位)和 Visual-Studio 2010。我总是编译我用 gcc (cygw
我喜欢在模板类中使用本地类来执行类似“static if”的构造。但是我遇到了 gcc 4.8 不想编译我的代码的问题。但是 4.7 可以。 这个例子: #include #include #in
我有一个项目,必须仅使用 java 1.4 进行编译。但我计划使用mockito 编写一些单元测试。我想要一种在 pom 中指定的方法,以便 src/main/java 使用 jdk 1.4 编译,但
我想了解 PHP 编译过程是如何工作的。 假设我有一个名为funcs.php 的文件并且这个文件有三个函数,如果我include 或require 它,所有的在文件加载期间编译三个函数?或者源代码会被
编译工具链 我们写程序的时候用的都是集成开发环境 (IDE: Integrated Development Environment),集成开发环境可以极大地方便我们程序员编写程序,但是配置起来
当我编写一些 Scala 代码时,在尝试编译代码时收到一条奇怪的错误消息。我将代码分解为一个更简单的代码(从语义的角度来看这完全没有意义,但仍然显示了错误)。 scala> :paste // Ent
我正在编译一个 SCSS 文件,它似乎删除了我的评论。我可以使用什么命令来保留所有评论? >SASS input.scss output.css 我在 SCSS 中看到两种类型的注释。 // Comm
这是我的代码: #include typedef struct { const char *description; float value; int age; } swag
当您编译 grails war 时,我知道 .groovy 代码被编译为字节码类文件,但我不明白容器(例如 tomcat)如何在请求 GSP 时知道如何编译它们。容器了解 GSP 吗?安装在服务器上的
我正在努力将多个文件编译成一个通用程序。我收到一个错误: undefined reference to 'pi' 这是我的代码和 Makefile 的框架。我做错了什么?谢谢! 文件:calcPi.c
我尝试使用 LD_PRELOAD 来 Hook sprintf function ,所以我将打印到缓冲区的结果: #define _GNU_SOURCE #include #include int
我正在寻找最简单的方法来自动将 CoffeeScript 重新编译为 JS。 阅读documentation但仍然很难得到我想要的东西。 我需要它来监视文件夹 src/ 中的任何 *.coffee 文
我想使用定制waveformjs 。我发现this on SO但是,我不知道如何编译/安装波形来开始。我从 GitHub 克隆它并进行了更改,但是我不知道如何将其转换为 .js 文件。 最佳答案 为了
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我是一名优秀的程序员,十分优秀!