如何找到伴随对象所有者的KClass



我正试图获得拥有一个伴随对象的类,这样我就可以在伴随对象内使用内联技术创建记录器,但引用正在记录的主类,而不是伴随对象。

问题是,我找不到一种方法来获得伴随对象的所有者,我该怎么做?

fun Logger(c: Class<*>): Logger {
var c2 = c
val k = c.kotlin
if (k.isCompanion) {
c2 = k.<opposite of what companionObject does>.java
}
// Calls a factory, reuse the same instance if it already exists
return RootLogger.getChild(c2)
}
@Suppress("NOTHING_TO_INLINE")
inline fun Logger(): Logger {
return Logger(MethodHandles.lookup().lookupClass())
}

预期用例:

A:

class SomeClass {
companion object {
// Logger is inside a companion object
// But it must be the same as if it were created directly inside `SomeClass`
private val log = Logger()
}
fun someFun() = log.info("Hello")
}

B:

// can be object or anything else
class SomeClass {
// The same object is returned to all instances and would be the same object
// as if it were inside a companion object
private val log = Logger()
fun someFun() = log.info("Hello")
}

在JVM环境中,可以使用实现

k.java.enclosingClass.kotlin

因此,功能将是:

fun Logger(c: Class<*>): Logger {
var c2 = c
val k = c.kotlin
if (k.isCompanion) {
c2 = k.java.enclosingClass
}
// Calls a factory, reuse the same instance if it already exists
return RootLogger.getChild(c2)
}

可以用进行测试

internal class LoggerTest {
@Test
internal fun testUseCaseA() {
val fqn = UseCaseA::class.qualifiedName
assertEquals(fqn, UseCaseA.log.name)
val log = Logger(UseCaseA::class.java)
assertEquals(fqn, log.name)
assertSame(UseCaseA.log, log)
val log2 = Logger(UseCaseA.Companion::class.java)
assertEquals(fqn, log2.name)
assertSame(log, log2)
}
@Test
internal fun testUseCaseB() {
val fqn = UseCaseB::class.qualifiedName
val b1 = UseCaseB()
assertEquals(fqn, b1.log.name)
val log = Logger(UseCaseB::class.java)
assertEquals(fqn, log.name)
assertSame(b1.log, log)
val b2 = UseCaseB()
assertEquals(fqn, b2.log.name)
assertSame(b2.log, log)
}
private class UseCaseA {
companion object {
val log = Logger()
}
}
private class UseCaseB {
val log = Logger()
}
}

最新更新