2017-09-14 6 views
1

En utilisant la réflexion, il est possible d'implémenter des appels à des méthodes de classes non disponibles au moment de la compilation. C'est un moyen efficace de permettre au code cadre de fonctionner avec différentes versions de bibliothèques.Comment implémenter une interface non disponible sur compiletime

Maintenant, dire il y a une interface

interface FutureIntf { 
    method1(String s); 
} 

Mon code ne connaît pas encore cette interface, mais je voudrais préparer une mise en œuvre pour le moment, cette interface peut être mis à disposition par la future version de la bibliothèque , qui doit fonctionner avec une implémentation de cette interface. Je veux éviter javassist. Je pense qu'il devrait y avoir un moyen d'utiliser java.lang.reflect.Proxy.newProxyInstance, mais je n'ai pas encore compris, comment le faire efficacement.

Répondre

1

Vous devez d'abord récupérer l'interface. Ensuite, créez le proxy comme vous l'avez mentionné avec newProxyInstance. Enfin, vous pouvez appeler des méthodes sur l'interface ou publier le proxy dans un localisateur de service ou similaire.

Class<?> unknownInterface = ClassLoader.getSystemClassLoader().loadClass("bar.UnknownInterface"); 

Object proxy = Proxy.newProxyInstance(unknownInterface.getClassLoader(), 
             new Class[] { unknownInterface }, 
             new Handler()); 

unknownInterface.getMethod("someMethod", String.class).invoke(proxy, "hello"); 
// other way to call it: 
// ((UnknownInterface) proxy).someMethod("hello"); 

La classe gestionnaire représente la mise en œuvre que vous voulez fournir:

public class Handler implements InvocationHandler { 
    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
     if (method.getName().equals("someMethod")) { 
      System.out.println("this is the business logic of `someMethod`"); 
      System.out.println("argument: " + args[0]); 
      return null; 
     } 
     return null; 
    } 
} 

Quels sont les inconvénients ici:

  • Vous devez récupérer l'objet de classe de votre interface. Probablement vous avez besoin du nom de celui-ci.
  • a) Vous devez connaître les noms et les paramètres des méthodes
  • b) Ou si vous connaissez les types de paramètres des méthodes, vous pouvez les faire correspondre aux types et ignorer les noms, par ex. args.length == 1 && args[0].getClass == String.class

Basé sur this tutorial about proxies