动态创建一个Java类,并在运行时进行编译和实例化 [英] Create a java class dynamically and compile and instantiate at run time

查看:109
本文介绍了动态创建一个Java类,并在运行时进行编译和实例化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 String ,我需要将其转换为java类,在运行时编译并创建一个实例:
假设我的字符串是:

I have a String that I need to convert to java class, compile and create an instance at run time: Suppose my String is:

String s = " public class Test {
  public Double add(Double x, Double y){
    return (x+y);
  }
}"

如何将其转换为类 Test .class,将其实例化并调用方法 add(Double x,是Double y)在运行时吗?

How can I convert it to a class Test.class, instantiate it and call the method add(Double x, Double y) at run time?

我读到有关 Byte Buddy的信息,但是我看到的示例已经定义了一个类。在上述情况下,谁能举一个例子,说明如何使用ByteBuddy或任何其他可以实现此目的的库?

I read about Byte Buddy , but the examples I see has a class already defined. In a situation like the above, could anyone give an example how can I use ByteBuddy or any other libraries through which I can achieve this?

有关如何将此 String 转换为可编译和可实例化的Java类的任何输入或建议将很有帮助。

Any inputs or suggestions on how to convert this String to compilable and instantiable java class would be helpful.

推荐答案

我们可以使用这样的东西吗:

Can we use something like this :

package com.demo;

import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;

public class StringToClass
{
    public static void main(String[] args)
    {
        String s = "import com.demo.FormulaAPI; public class FormulaExecutor" +
                " { public Double formula1(FormulaAPI apiReference)" +
                " { System.out.println(apiReference.evaluate(\"10.10\"));  return apiReference.evaluate(\"10.10\"); } }";
        try
        {
            dynamicClass(s, "FormulaExecutor");
        } catch (IOException | NoSuchMethodException | ClassNotFoundException | IllegalAccessException | InstantiationException | InvocationTargetException e)
        {
            e.printStackTrace();
        }

    }

    static void dynamicClass(String sourceCode, String className) throws IOException, NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException
    {
        File parent = new File(System.getProperty("user.dir"));
        File sourceFile = new File(parent, className + ".java");
        sourceFile.deleteOnExit();

        FileWriter writer = new FileWriter(sourceFile);
        writer.write(sourceCode);
        writer.close();

        JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager standardJavaFileManager = javaCompiler.getStandardFileManager(null, null, null);
        File parentDir = sourceFile.getParentFile();
        standardJavaFileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(parentDir));
        Iterable<? extends JavaFileObject> compilationUnits = standardJavaFileManager.getJavaFileObjectsFromFiles(Arrays.asList(sourceFile));
        javaCompiler.getTask(null, standardJavaFileManager, null, null, null, compilationUnits).call();
        standardJavaFileManager.close();

        URLClassLoader urlClassLoader = URLClassLoader.newInstance(new URL[] {parentDir.toURI().toURL()});
        Class<?> dynamicClass = urlClassLoader.loadClass(className);


        Method formula1 = dynamicClass.getDeclaredMethod("formula1", FormulaAPI.class);
        formula1.invoke(dynamicClass.newInstance(), new Object[] {new FormulaAPI()});
    }


}



package com.demo;

public class FormulaAPI
{
    public Double evaluate(String str)
    {
        return Double.valueOf(str);
    }
}

现在,方法名称是硬编码的

For Now, Method name is hardcoded

        Method addMethod = dynamicClass.getDeclaredMethod("add", Double.class, Double.class);

我们甚至可以在运行时使用反射生成它

We can even generate it at runTime using reflection

我们可以在源代码中导入该类。

We can import the class in the source code.

这篇关于动态创建一个Java类,并在运行时进行编译和实例化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆