是否可以在运行时编译和实例化Kotlin类?我正在谈论类似的东西但是使用Kotlin API:How do I programmatically compile and instantiate a Java class?
例如: 我将完整的类定义作为String:
val example = "package example\n" +
"\n" +
"fun main(args: Array<String>) {\n" +
" println(\"Hello World\")\n" +
"}\n"
然后将其插入某个class.kt并运行它,以便我得到#34; Hello World&#34;在运行时打印在控制台中。
答案 0 :(得分:1)
您可能需要查看Kotlin脚本,请参阅https://github.com/andrewoma/kotlin-script
或者,您需要编写自己的eval(kotlin-code-string-here)
方法,将文本转储到blah.kt
文件中,例如,使用外部Kotlin编译器将其编译为blah.class
然后动态加载这些类使用Java Classloader进入运行时,执行如下操作:
MainClass.class.classLoader.loadClass("com.mypackage.MyClass")
这可能非常缓慢且不可靠。
另一个不太好的选择是使用Rhino并在Kotlin代码中运行JavaScript。所以再次,你将有一个eval(kotlin-code-string-here)
方法将内容转储到blah.kt
文件,然后你将使用Kotlin2JS编译器将其编译为JavaScript并使用Rhino直接在Kotlin中执行JavaScript这也不是很好。
另一种选择是使用Kotlin Scripting或外部Kotlin编译器(在两种情况下,Kotlin编译器都必须启动)并且做这样的事情也将允许你动态执行,尽管只在Unix系统上
Runtime.getRuntime().exec(""" "kotlin code here" > blah.kts | sh""")
我不知道有一个干净的解决方案,Kotlin的设计不像PHP / JavaScript / Python那样只是动态地解释文本,它必须先编译成字节码才能在JVM上做任何事情;因此,在每个场景中,您将需要首先以某种方式编译该代码,无论是字节码还是javascript,并且在两种情况下都使用Java Classloader或Rhino将其加载到您的应用程序中。
答案 1 :(得分:0)
请检查this solution的依赖关系,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"))
请注意:此处可以进行代码注入。请小心,并为此使用专用的进程或专用的ClassLoader。