2014-06-26 57 views
1

我有一個將在運行時編譯的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

反思,也許? – awksp

+0

我想出了使用Relection - 基於這裏給出的答案:我想出了使用Relection - 基於給出的答案[這裏] [1] http://stackoverflow.com/questions/160970/how-do -i-invoke -a-java-method-when-method-the-method-name-as-a-string – Aneesh

回答

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! 
+0

這將會起作用 - 但我無法控制源代碼。它由一個外部程序生成。但是對詳細的答案進行投票。 – Aneesh

相關問題