0

我正在使用 ecj 进行遗传编程,并且我已经构建了它,因此它在运行后采用最适合的单个程序,并使用创建的 lisp 代码中的函数创建一个 java 类。

然后我让我的程序编译 java 文件。无论如何我可以在同一次运行中运行新编译的类文件吗?

我希望能够:

RunMain --> 创建 Java --> 编译类 --> 在新创建的类中调用函数 --> EndMainRun

到目前为止,我无法在新创建的类中调用该方法。

每次我创建新的 java 文件并编译时,它都会重写旧的。但是,每当稍后调用该类时,它都会运行旧函数 pre-overwrite。任何提示将不胜感激!

编辑:这里有一些非常基本的伪代码来展示我到目前为止所拥有的东西,其中很多都是抽象的。假设在我运行它之前已经有一个 MathFunction.class 文件。

PseudoCode
Main(){
runGeneticProgrammingAlgorithm();
generateJavaFileFromBestFitIndividual(name = MathFunction.java) //Replaces old MathFunction.java
compile(MathFunction.java) //using JavaCompilerApi, replaces old MathFunction.class
double value = MathFunction.calculate(25);

旧函数返回值 -1,新函数应该返回 5,但它仍然返回 -1。即使我把这一切都放在一个循环中,它也会不断吐出 -1、-1、-1....

编辑2:

尽管功能完全不同,但我仍然让它返回相同的值。这是代码:

    URL[] urls = null;

    File dir = new File("src" + java.io.File.separator + "ec");

    URL url = dir.toURI().toURL();

    urls = new URL[] { url };

    ClassLoader cl = new URLClassLoader(urls);

    Class cls = cl.loadClass("ec.MathSolution");

    MathSolution mathFunction = (MathSolution) cls.newInstance();

    System.out.println(mathFunction.calculate(123.5));

编辑3:

在这里在线找到了一个惊人的来源:http ://www.toptal.com/java/java-wizardry-101-a-guide-to-java-class-reloading

4

1 回答 1

1

实现你想做的事情并非易事,但通过一些类加载器魔法很容易实现。

您说“它正在运行旧函数 pre-overwrite”这一事实表明您正在从第一次获得它的同一个类加载器创建此类的实例。

我建议阅读 ClassLoaders。

在高层次上,您的算法应该是:

  1. 创建java
  2. 编译类
  3. 创建一个作为当前类加载器子级的 ClassLoader。
  4. 使用这个类加载器加载在第 2 步编译的类
  5. 实例化该类或以其他方式使用它。
  6. 现在你看到有一个新的修订......从 1 开始

我将尝试使用一些代码示例来编辑此答案。

于 2015-04-29T06:35:26.703 回答