Como verificar se uma classe tem anulado um método padrão a partir de uma interface usando Reflexão em Kotlin ou Java?

harold_admin:

Eu tenho uma interface com um método padrão, e duas classes que implementam esta interface. Uma das classes substitui o método padrão, e o outro não.

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

Eu ter acesso ao giveHellométodo usando reflexão como esta:

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

Há uma coisa estranha aqui. A classe educado não substitui o giveHellométodo, mas o declaringClassdeste objeto método ainda aponta para Polite.

Então, há uma maneira que eu possa verificar se a classe realmente se substituir o método interface padrão ou não?

Meu caso de uso é algo como isto (assumindo que podemos obter o comportamento que eu estou pedindo em uma propriedade chamada isOverriden):

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

Conforme descrito na KT-4779 , actualmente funções padrão KOTLIN não são implementados usando métodos efetivos padrão Java / JVM. As vidas de implementação padrão em um método estático em vez, e todas as classes que usam essa implementação padrão apenas chamar esse método estático. Isto é feito para assegurar funções padrão KOTLIN também trabalho na JVM alvo 1.6 que não tem ainda.

Portanto, o seu código de aproximadamente compila a este equivalente 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" }
}

É por isso que java reflexão pensa ambas as classes substituir a função, ou seja, porque eles realmente fazem.

Você precisa usar Kotlin reflexão aqui, nomeadamente declaredMemberFunctionse 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

Acho que você gosta

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