调用在运行时编译的类的自定义方法

时间:2014-06-26 04:20:05

标签: java

我有一个java源代码,可以在运行时编译。 我正在编译源代码(以字符串形式出现)并将其加载到类中,如下所示:

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        compiler.run(null, null, null, sourceFile.getPath());


        // Load and instantiate compiled class.
        URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
        Class<?> cls = Class.forName("TakeAdvantageOftMapComponents", true, classLoader);

这个类包含一个我需要调用名为runJob的方法。通常我会这样做:

TakeAdvantageOftMapComponents c  = new TakeAdvantageOftMapComponents();
c.runJob(new string[]);

现在,我在运行时编译的类中存在同样的方法。但我怎么称呼它?

1 个答案:

答案 0 :(得分:1)

优于使用反射来调用您想要的方法,您可能希望声明您的类会扩展的interface ,例如:

package ccjmne;

public interface JobRunner {

    public void runJob(final String[] args);
}

...并使您的课程实施 interface

文件: /home/eric/stackoverflow/A.java

package stackoverflow;

public class A implements ccjmne.JobRunner {
    public void runJob(final String args[]) {
        for(final String str : args) {
            System.out.println(str);
        }
    }
}

最后,按如下方式加载该类:

final Class<JobRunner> cls = (Class<JobRunner>) Class.forName("stackoverflow.A", true, classLoader);

请注意,我知道我在这里JobRunner

因此,我可以这样做:

cls.newInstance().runJob("Hello world!".split(" "));

......你已经完成了!


示例工作代码:

package ccjmne;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

public class JobRunnerTest {

    public static void main(final String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException {
        final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        final File root = new File("/home/eric/");
        compiler.run(null, null, null, root + "/stackoverflow/A.java");
        final URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
        final Class<JobRunner> cls = (Class<JobRunner>) Class.forName("stackoverflow.A", true, classLoader);
        cls.newInstance().runJob("Hello world!".split(" "));
    }
}

输出:

Hello
world!