如何使用 Kotlin 或 Java 中的 Reflection 检查类是否覆盖了接口的默认方法?

我有一个带有默认方法的接口,以及两个实现该接口的类。其中一个类会覆盖默认方法,而另一个则不会。


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")

这里有一件奇怪的事情。礼貌类不会重写该giveHello方法,但declaringClass该方法对象的 仍然指向Polite。


那么有没有一种方法可以检查该类是否确实覆盖了默认的接口方法?


我的用例看起来像这样(假设我们可以在名为 的属性中获得我所要求的行为isOverriden):


if (methodOfPolite.isOverriden) {

  // do something

} else {

  // do something else

}


HUWWW
浏览 119回答 2
2回答

慕哥9229398

如KT-4779中所述,目前 Kotlin 默认函数并未使用实际的 Java/JVM 默认方法来实现。默认实现位于静态方法中,所有使用该默认实现的类都只调用该静态方法。这样做是为了确保 Kotlin 默认函数也可以在尚不具备这些函数的 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.declaredFunctionsprintln(overridesGiveHello(Polite::class)) //falseprintln(overridesGiveHello(Rude::class))  //true

饮歌长啸

在这种特定情况下,我认为该isDefault()方法应该返回true.我本希望Polite::class.java.getMethod("giveHello")返回该方法,但没有getDeclaredMethod(),但我们正处于在 Kotlin 类和接口上使用 Java 反射的世界中。Java 的期望可能无法得到满足。不过,您可以使用 kotlin 反射,用于declaredMembers从KClass. kotlin.reflect.full请注意,由于使用了扩展方法,因此需要导入。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java