Cómo comprobar si una clase ha anulado un método predeterminado de una interfaz mediante la reflexión en Kotlin o Java?

harold_admin:

Tengo una interfaz con un método predeterminado, y dos clases que implementan esta interfaz. Una de las clases reemplaza el método por defecto, y el otro no.

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

Consigo el acceso al giveHellométodo que utiliza la reflexión de esta manera:

val methodOfPolite = Polite::class.java.getDeclaredMethod("giveHello")
val methodOfRude = Rude::class.java.getDeclaredMethod("giveHello")

Hay una cosa extraña aquí. La clase educado no anula el giveHellométodo, pero el declaringClassde este método objeto todavía señala a Polite.

Entonces, ¿hay alguna manera de comprobar si la clase de hecho no anula el método de interfaz por defecto o no?

Mi caso de uso es como la siguiente (suponiendo que podemos obtener el comportamiento que estoy pidiendo en una propiedad llamada isOverriden):

if (methodOfPolite.isOverriden) {
  // do something
} else {
  // do something else
}
Todd Sewell:

Como se describe en KT-4779 , actualmente funciones predeterminadas Kotlin no se implementan utilizando métodos actuales por defecto de Java / JVM. Las vidas de aplicación por defecto en un método estático en lugar, y utilizando todas las clases que la aplicación por defecto simplemente llaman a ese método estático. Esto se hace para asegurar las funciones predeterminadas Kotlin también a trabajar en el objetivo 1.6 JVM que no tiene todavía.

Por lo que su código se compila más o menos equivalente a este de 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" }
}

Esta es la razón por la reflexión de Java piensa que ambas clases tienen prioridad sobre la función, es decir, debido a que realmente hacen.

Es necesario utilizar Kotlin reflexión aquí, en particular declaredMemberFunctions, y 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

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=312091&siteId=1
Recomendado
Clasificación