Kotlin class 与同伴一起重新加载 objects/functions

Kotlin class reloading with companion objects/functions

我正在尝试使用 Kotlin class 重新加载,但我最近遇到了类似的问题:

package com.aurieh.reloading
fun doSomething(): String { // a function that does not belong to the class,
    // so it gets compiled as FileName$doSomething$...
}

class FileName {
    // do things with doSomething
}

如果我重新加载此 class(使用 ImplClassLoader.defineClassByteArray),并尝试调用在内部调用 doSomething 的方法,我会收到类似于以下内容的错误:

java.lang.IllegalAccessError: tried to access method com.aurieh.reloading.FileName.doSomething$default()Ljava/lang/String; from class com.aurieh.ares.reloading.FileName`

我会将其解释为好像重新加载的 class 没有附加 doSomething.. 所以我的问题是,我将如何解决这个错误?通过某种方式将 doSomething 附加到重新加载 classloader?

作为参考,我的class重新加载代码:

class Reloader : ClassLoader() {
    fun load(name: String, bytes: ByteArray, offset: Int, len: Int): Class<*> {
        return defineClass("com.aurieh.reloading.$name", bytes, offset, len)
    }
}

并加载:

val bytes = File("../classes/path/to/class/FileName.class").readBytes()
Reloader().load("FileName", bytes, 0, bytes.size).newInstance()

基本上,top-level 函数不会编译到文件中定义的任何 classes 中。相反,为 top-level 成员创建了一个单独的 class:FileNameKt(如果文件名为 FileName.kt)。

因此,为了让您的 class 正确加载(即没有任何不满意的链接),您必须首先加载 FileNameKt class:

val bytes1 = File("../classes/path/to/class/FileNameKt.class").readBytes()
val bytes2 = File("../classes/path/to/class/FileName.class").readBytes()
val reloader = Reloader()
reloader.load("FileNameKt", bytes1, 0, bytes1.size)
reloader.load("FileName", bytes2, 0, bytes2.size).newInstance()