我有一个带有默认方法的接口(interface),以及两个实现该接口(interface)的类。其中一个类覆盖了默认方法,而另一个则没有。
interface MyType {
fun giveHello(): String = "Hello!"
}
class Polite: MyType {
// Does not override giveHello()
}
class Rude: MyType {
override fun giveHello(): String = "I don't like you"
}
我可以像这样使用反射访问 giveHello
方法:
val methodOfPolite = Polite::class.java.getDeclaredMethod("giveHello")
val methodOfRude = Rude::class.java.getDeclaredMethod("giveHello")
这里有一件奇怪的事情。 polite类并没有覆盖giveHello
方法,但是这个方法对象的declaringClass
仍然指向Polite
。
那么有没有一种方法可以检查该类是否确实覆盖了默认接口(interface)方法?
我的用例看起来像这样(假设我们可以在名为 isOverriden
的属性中获得我要求的行为):
if (methodOfPolite.isOverriden) {
// do something
} else {
// do something else
}
最佳答案
如 KT-4779 中所述,目前 Kotlin 默认函数不是使用实际的 Java/JVM 默认方法实现的。默认实现存在于静态方法中,所有使用该默认实现的类都只调用该静态方法。这样做是为了确保 Kotlin 默认函数也可以在 1.6 JVM 目标上工作,而 1.6 JVM 目标还没有。
所以你的代码大致编译成这个 Java 等价物:
public interface MyType {
public String giveHello();
public static class MyTypeImpls {
public static String giveHello() { return "Hello!" }
}
}
public final class Polite implements MyType {
//does not override
public String giveHello() { return MyType.MyTypeImpls.giveHello() }
}
public final class Rude implements MyType {
//does override
override fun giveHello() { return "I don't like you" }
}
这就是为什么 java 反射认为两个类都覆盖了函数,即因为它们确实这样做了。
你需要在这里使用 Kotlin 反射,特别是 declaredMemberFunctions
和 memberFunctions
:
fun overridesGiveHello<T: MyType>(cls: KClass<T>) =
cls.memberFunctions.first { it.name == "giveHello" } in cls.declaredFunctions
println(overridesGiveHello(Polite::class)) //false
println(overridesGiveHello(Rude::class)) //true
关于java - 如何检查类是否已使用 Kotlin 或 Java 中的反射覆盖接口(interface)中的默认方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58047229/