2012-06-04 3 views
1

Я знаю, что есть, вероятно, что-то делать с загрузчиков классов, но я не мог найти пример (это может быть я Google-ING для неправильных ключевых словJava:. Класс нагрузки из строки

Я пытается загрузить класс (или метод) образуют строку строка не содержит имя класса, но код для класса, например

class MyClass implements IMath { 
    public int add(int x, int y) { 
     return x + y; 
    } 
} 

, а затем сделать что-то вроде этого:.

String s = "class MyClass implements IMath { public int add(int x, int y) { return x + y; }}"; 
IMath loadedClass = someThing.loadAndInitialize(string); 
int result = loadedClass.add(5,6); 

Теперь, очевидно, someThing.loadAndInitialize(string) - часть, которую я не знаю, как ее достичь. Возможно ли это? Или было бы проще запускать JavaScripts и как-то «давать» переменные/объекты (например, x и y)?

Благодарим за любые советы.

+0

http://stackoverflow.com/questions/1168931/how-to-create-an-object-from-a-string-in-java-how-to -eval-a-string – nullpotent

+0

Лично, если источник * имел * быть Java, я бы просто использовал API компиляции Java, или если этого было недостаточно, Janino, javassist и т. д. –

ответ

7

Используйте API компилятора Java. Here - это сообщение в блоге, в котором показано, как это сделать.

Для этого можно использовать временные файлы, так как для этого требуется файл ввода-вывода, или вы можете создать собственную реализацию JavaFileObject, которая считывает исходный код из строки. Из javadoc:

/** 
    * A file object used to represent source coming from a string. 
    */ 
    public class JavaSourceFromString extends SimpleJavaFileObject { 
     /** 
     * The source code of this "file". 
     */ 
     final String code; 

     /** 
     * Constructs a new JavaSourceFromString. 
     * @param name the name of the compilation unit represented by this file object 
     * @param code the source code for the compilation unit represented by this file object 
     */ 
     JavaSourceFromString(String name, String code) { 
      super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), 
       Kind.SOURCE); 
      this.code = code; 
     } 

     @Override 
     public CharSequence getCharContent(boolean ignoreEncodingErrors) { 
      return code; 
     } 
    } 

После того, как у вас есть выходной файл (который скомпилированный .class файл), вы можете загрузить его, используя URLClassLoader следующим образом:

ClassLoader loader = new URLClassLoader(new URL[] {myClassFile.toURL()); 
    Class myClass = loader.loadClass("my.package.MyClass"); 

, а затем создать его экземпляр, используя:

myClass.newInstance(); 

или с помощью Constructor.

+0

Спасибо, я didn Не знаю о компиляторе api :-) –

2

Вы можете использовать Rhino и JavaScript в JDK 7. Это может быть хорошим способом сделать это.

invokedynamic приходит ....

Если вы хотите придерживаться Java, вам нужно что-то разобрать источник и превратить его в байт-код - что-то вроде CGLIB.

0

Вы можете скомпилировать его с помощью JavaCompiler, но я предлагаю вам использовать Groovy для создания этого времени выполнения. Было бы намного проще.

0

Сначала вам необходимо скомпилировать код, например, используя API-интерфейс компилятора: (http://www.accordess.com/wpblog/an-overview-of-java-compilation-api-jsr-199/, http://docs.oracle.com/javase/6/docs/api/javax/tools/package-summary.html). И после этого загрузить скомпилированный класс с ClassLoader (http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ClassLoader.html)