为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

HUWWW 2023-08-16 17:25:44
我有一个带有默认方法的接口,以及两个实现该接口的类。其中一个类会覆盖默认方法,而另一个则不会。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}
查看完整描述

2 回答

?
慕哥9229398

TA贡献1877条经验 获得超6个赞

如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.declaredFunctions


println(overridesGiveHello(Polite::class)) //false

println(overridesGiveHello(Rude::class))  //true


查看完整回答
反对 回复 2023-08-16
?
饮歌长啸

TA贡献1951条经验 获得超3个赞

在这种特定情况下,我认为该isDefault()方法应该返回true.

我本希望Polite::class.java.getMethod("giveHello")返回该方法,但没有getDeclaredMethod(),但我们正处于在 Kotlin 类和接口上使用 Java 反射的世界中。Java 的期望可能无法得到满足。

不过,您可以使用 kotlin 反射,用于declaredMembersKClasskotlin.reflect.full请注意,由于使用了扩展方法,因此需要导入。


查看完整回答
反对 回复 2023-08-16
  • 2 回答
  • 0 关注
  • 118 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信