Kotlin在运行时从源代码动态编译类

Kotlin在运行时从源代码动态编译类,kotlin,Kotlin,可以在运行时编译和实例化Kotlin类吗?我说的是类似的东西,但使用Kotlin API: 例如: 我得到了字符串的完整类定义: val example = "package example\n" + "\n" + "fun main(args: Array<String>) {\n" + " println(\"Hello World\")\n" + "}\n" val example=“包示例\n”+ “\n

可以在运行时编译和实例化Kotlin类吗?我说的是类似的东西,但使用Kotlin API:

例如: 我得到了字符串的完整类定义:

val example = "package example\n" +
        "\n" +
        "fun main(args: Array<String>) {\n" +
        "    println(\"Hello World\")\n" +
        "}\n"
val example=“包示例\n”+
“\n”+
“有趣的主(参数:数组){\n”+
“println(\“Hello World\”)\n”+
“}\n”

然后将其插入某个class.kt并运行它,以便在运行时在控制台中打印“Hello World”。

您可能想了解Kotlin脚本,请参阅

或者,您需要编写自己的
eval(此处为kotlin代码字符串)
方法,该方法将在
blah.kt
文件中转储文本,例如,使用外部Kotlin编译器将其编译到
blah.class
中,然后使用Java类加载器将这些类动态加载到运行时,如下所示:

MainClass.class.classLoader.loadClass("com.mypackage.MyClass")
这可能是非常缓慢和不可靠的

另一个不太好的选择是使用Rhino并在Kotlin代码中运行JavaScript。所以再一次,您将有一个
eval(这里是kotlin代码字符串)
方法,该方法将内容转储到
blah.kt
文件中,然后您将使用Kotlin2JS编译器将其编译为JavaScript,并使用Rhino直接在kotlin内部执行JavaScript,这也不太好

另一种选择是使用Kotlin脚本或外部Kotlin编译器(在这两种情况下,Kotlin编译器都必须启动),这样做也将允许您动态执行,尽管只能在Unix系统上执行

Runtime.getRuntime().exec("""  "kotlin code here" > blah.kts | sh""")
我不知道有没有一个干净的解决方案,Kotlin的设计不像PHP/JavaScript/Python那样运行,它只是动态地解释文本,它必须先编译成字节码,然后才能在JVM上执行任何操作;因此,在每种情况下,您都需要先以某种方式编译代码,无论是字节码还是javascript,并在这两种情况下使用Java Classloader或Rhino将其加载到您的应用程序中。

请检查依赖项、jar资源等。下面的代码不足以成功执行

但是,要编译动态类,可以执行以下操作:

val classLoader = Thread.currentThread().contextClassLoader

val engineManager = ScriptEngineManager(classLoader)

setIdeaIoUseFallback() // hack to have ability to do this from IntelliJ Idea context

val ktsEngine: ScriptEngine = engineManager.getEngineByExtension("kts")

ktsEngine.eval("object MyClass { val number = 123 } ")

println(ktsEngine.eval("MyClass.number"))

请注意:这里可能有代码注入。请小心使用专用进程或专用类加载器。在运行时编写类的好处是什么?为什么不能用传入的参数对其进行抽象来设置呢?这不是一个正确的答案,但请看一看可能的操作指南。分叉Kotlin编译器不算作动态计算。