简体   繁体   English

如何检查 class 是否使用 Kotlin 或 Java 中的反射从接口覆盖了默认方法?

[英]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 反射,特别是declaredMemberFunctionsmemberFunctions

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 反射,使用declaredMembersKClass获取属性和函数。 Note, import from kotlin.reflect.full is required, since extension methods are used.注意,需要从kotlin.reflect.full导入,因为使用了扩展方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Scala 中,给定一个子类,如何使用反射检查它是否覆盖了其父接口(用 Java 定义)的默认方法? - In Scala, given a subclass, how to check if it overrides the default method of its parent interface (defined in Java) using reflection? 从类调用实现的接口覆盖方法 - Call implemented interface overriden method from a class 如何使用反射判断接口是否有默认方法? - how to use reflection to determine whether an Interface has a default method? Kotlin class 实现 Java 接口使用默认方法实现,而不是覆盖 - Kotlin class that implements Java interface is using default method implementations, rather than overrides Java:如何使用反射检查方法是否被覆盖 - Java: How to check if a method is overridden, using reflection 如何更改从实现到我正在使用的具体类的接口覆盖的方法的签名? - How do I change the signature of a method I have overriden from my interface that I implemented onto the concrete class I'm using? 如何在 Kotlin 中惯用地编写 Java 函数接口的默认方法? - How to write Java's default method of a functional interface in Kotlin idiomatically? 如何使用Java Kotlin编写的接口中默认方法的8个特性 - How to use Java 8 feature of default method in interface written in Kotlin 如何在 Java 中使用反射调用 Kotlin object 方法? - How to invoke Kotlin object method using reflection in Java? Java派生类的反射调用默认方法 - Java reflection call default method from derived class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM