在运行时动态构建java / scala方法体并执行它

时间:2015-05-31 19:15:14

标签: java scala reflection

假设我在java中有以下接口:

public interface DynamicMethod {
    String doit();
}

我想在运行时构建一个符合上述接口的Object,以便在其中注入doit方法体,然后执行它?这可能是使用Java Reflection API或任何其他方式吗?或者可能在Scala中以某种方式?

请注意,我的对象的doit正文是动态的,并且不是先验的。您可以假设在运行时提供了一个数组CodeArray[1..10]的字符串,并且此数组的每个条目都包含每个doit方法的代码。如果您能回答示例代码,我将不胜感激。

上下文: 我试着解释问题的背景;尽管如此,上述问题仍然与上下文无关。

我有一些命令说C1,C2,......;每个命令都有一定的参数。根据命令及其参数,系统需要执行某个任务(使用java代码表示)。我需要根据用户需求存储这些命令以供将来执行(所以上面的CodeArray[1..10]保存这个java代码列表)。例如,用户从列表中选择一个命令(即,从数组中选择)并要求执行它。

我的想法是我构建了一个基于用户选择的引擎,从数组中加载相应的命令代码并执行它。

3 个答案:

答案 0 :(得分:1)

根据您添加的背景信息,我觉得您有一个Interpreter.

例如,SQL接受类似" SELECT * FROM users"的输入,解析并构建一个然后解释的标记树。

另一个例子:Java的正则表达式是一个解释器。像" [abc] +"被编译成令牌,然后在执行时解释。您可以在source code.

中看到它使用的令牌(称为Node

我稍后会尝试发布一个简单的示例,但解释器模式不会使用动态生成的代码。所有的代币都是具体的类。您必须定义所有可能的(有效)用户输入,以便您可以创建令牌来执行它。 SQL和regex有一个定义的语法,你也需要一个。

答案 1 :(得分:1)

我认为Byte Buddy会对你的情况有所帮助。这是一个由备受尊敬的Java开发人员维护的开源项目。

看看学习部分,他们在那里有一个非常详细的例子: http://bytebuddy.net/#/tutorial

答案 2 :(得分:0)

目前还不是很清楚你的目标是什么。根据您的要求,有很多方法可以做到这一点。

在某些情况下,创建ProxyInvocationHandler就足够了。有时生成Java源是合理的,然后在运行时调用JavaCompiler并使用URLClassLoader加载生成的类(如果您正在谈论代码字符串,可能就是这种情况)。有时最好使用ASMcglibBCEL等库直接创建字节码。