java - 如何检查类是否已使用 Kotlin 或 Java 中的反射覆盖接口(interface)中的默认方法?

标签 java kotlin reflection

我有一个带有默认方法的接口(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 反射,特别是 declaredMemberFunctionsmemberFunctions :

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/

相关文章:

java - 从对象列表生成 CSV

c# - 如何将通过反射获得的方法分配给委托(delegate)? (或 : how to speed up method calls through reflection)

reflection - 如何在接口(interface) slice 上设置结构变量的值?

android - 观察一个 MutableLiveData 列表

java - 如何使用 Firebase 从上传的文件中获取下载网址

java - ActionListener 无法识别来自主类的变量

java - 如何使用GSON解析JSON?

kotlin - 如何在 Kotlin 的列表中创建包含每两个项目的 map ?

java - 获取文件的总大小(以字节为单位)

java - 为什么执行 Mockito 模拟的性能如此不稳定?