2 votes

Invocation de méthodes non virtuelles à l'aide de la réflexion

En Java, lorsque l'on travaille avec java.lang.reflect.Method comment puis-je invoquer une fonction sans que ce soit un appel virtuel ?

C'est-à-dire que je veux que ce code imprime "bon" au lieu de ce qu'il fait actuellement, c'est-à-dire imprimer "mauvais" :

Foo.java :

public class Foo {
  public void doit() {
    System.out.println("good");
  }
}

Bar.java :

import java.lang.reflect.Method;

public class Bar extends Foo {
  public void doit() {
    System.out.println("bad");
  }

  public static void main(String[] args) throws Exception {
    Bar b = new Bar();
    /* Using Foo.class ought to do it right? */
    Method m = Foo.class.getDeclaredMethod("doit", new Class[]{});
    /* Surely if that didn't do it casting to Foo would? */
    m.invoke((Foo)b, new Object[]{});
  }
}

Rien de ce que je fais en utilisant la réflexion ne réussit à imprimer "bien".

Je m'attendais à ce que l'utilisation d'une ou de plusieurs méthodes d'analyse du premier argument de l'option invoke a Foo et/ou en utilisant Foo.class.getDeclaredMethod au lieu de Bar.class serait suffisant. Il est clair que je me trompe, comment puis-je obtenir le comportement souhaité tout en utilisant la réflexion ?

3voto

Flexo Points 39273

Il semble que la solution la plus simple soit d'utiliser la fonction java.lang.invoke qui possède une méthode appelée unreflectSpecial qui simule et invoque une instruction spéciale :

import java.lang.reflect.Method;
import java.lang.invoke.*;

public class Bar extends Foo {
  public void doit() {
    System.out.println("bad");
  }

  public static void main(String[] args) throws Throwable {
    Bar b = new Bar();
    Method m = Foo.class.getDeclaredMethod("doit", new Class[]{});
    MethodHandle h = MethodHandles.lookup().unreflectSpecial(m, Bar.class);
    h.invoke(b);
  }
}

Qui imprime effectivement "bon"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X