[英]How to check if a class has overriden a default method from an interface using Reflection in Kotlin or Java?
I have an interface with a default method, and two classes which implement this interface.我有一个带有默认方法的接口,以及两个实现该接口的类。 One of the classes overrides the default method, and the other does not.
其中一个类会覆盖默认方法,而另一个则不会。
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"
}
I get access to the giveHello
method using reflection like this:我可以像这样使用反射访问
giveHello
方法:
val methodOfPolite = Polite::class.java.getDeclaredMethod("giveHello")
val methodOfRude = Rude::class.java.getDeclaredMethod("giveHello")
There's one weird thing here.这里有一件奇怪的事情。 The polite class does not override the
giveHello
method, but the declaringClass
of this method object still points to Polite
.礼貌的 class 并没有覆盖
giveHello
方法,但是这个方法的 declaringClass declaringClass
仍然指向Polite
。
So is there a way I can check whether the class actually did override the default interface method or not?那么有没有办法可以检查 class 是否确实覆盖了默认接口方法?
My use case looks something like this (assuming we can get the behaviour I'm asking for in a property called isOverriden
):我的用例看起来像这样(假设我们可以在名为
isOverriden
的属性中获得我要求的行为):
if (methodOfPolite.isOverriden) {
// do something
} else {
// do something else
}
As described in KT-4779 , currently Kotlin default functions are not implemented using actual Java/JVM default methods.如KT-4779中所述,目前 Kotlin 默认函数未使用实际的 Java/JVM 默认方法实现。 The default implementation lives in a static method instead, and all classes using that default implementation just call that static method.
默认实现存在于 static 方法中,所有使用该默认实现的类只调用该 static 方法。 This is done to ensure Kotlin default functions also work on the 1.6 JVM target which doesn't have them yet.
这样做是为了确保 Kotlin 默认函数也适用于 1.6 JVM 目标,该目标还没有它们。
So your code roughly compiles to this Java equivalent:因此,您的代码大致编译为此 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" }
}
This is why java reflection thinks both classes override the function, ie because they actually do.这就是为什么 java 反射认为这两个类都覆盖了 function,即因为它们确实如此。
You need to use Kotlin reflection here, notably declaredMemberFunctions
and memberFunctions
:您需要在这里使用 Kotlin 反射,特别是
declaredMemberFunctions
和memberFunctions
:
fun overridesGiveHello(cls: KClass<Derp>) =
cls.memberFunctions.first { it.name == "giveHello" } in cls.declaredFunctions
println(overridesGiveHello(Polite::class)) //false
println(overridesGiveHello(Rude::class)) //true
In this specific case I think the isDefault()
method should return true
.在这种特定情况下,我认为
isDefault()
方法应该返回true
。
I would have expected Polite::class.java.getMethod("giveHello")
to return the method, but not getDeclaredMethod()
, but we are in the world of using Java reflection on Kotlin classes and interfaces. I would have expected
Polite::class.java.getMethod("giveHello")
to return the method, but not getDeclaredMethod()
, but we are in the world of using Java reflection on Kotlin classes and interfaces. The Java expectations may not be met.可能无法满足 Java 的期望。
You could use kotlin reflection though, use declaredMembers
to get the properties and functions from the KClass
.不过,您可以使用 kotlin 反射,使用
declaredMembers
从KClass
获取属性和函数。 Note, import from kotlin.reflect.full
is required, since extension methods are used.注意,需要从
kotlin.reflect.full
导入,因为使用了扩展方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.