2011-02-04 3 views
2

Je développe une application qui utilise l'interface Java comme plus qu'une interface Java, c'est-à-dire, Pendant l'exécution, l'utilisateur devrait pouvoir lister les méthodes disponibles dans la classe d'interface, qui peut être quelque chose:Java Interface Reflection Alternatives

private Class<? extends BaseInterface> interfaceClass. 

Lors de l'exécution, je voudrais enum les méthodes disponibles, puis en fonction de ce que l'utilisateur choisit, invoquer une méthode.

Ma question est: Est-ce que l'architecture Java "Interface" fournit une méthode pour peek et invoquer des méthodes sans utiliser l'API Reflection?

Je souhaite qu'il y ait quelque chose comme ça (peut-être il y a):

private Interface<? extends BaseInterface> interfaceAPI; 

public void someMethod(){ 
interfaceAPI.listMethods(); 
interfaceAPI.getAnnotations(); 
} 

Peut-être il y a une façon d'utiliser type Génériques pour accomplir ce que je veux?

Merci,

Phaedrus

+0

Il existe d'autres moyens, mais ils sont bien pires à mon humble avis. Vous n'avez pas dit pourquoi vous ne voulez pas utiliser la réflexion. Peut-être que vos préoccupations peuvent être traitées. –

+0

vous pouvez générer du code à la volée (et le charger via un chargeur de classe personnalisé) ... mais c'est ce que la réflexion fait réellement. – bestsss

Répondre

5

C'est exactement ce à quoi Reflection a été construit.

1

Ma question est la suivante: Est-ce que l'architecture Java "Interface" fournir une méthode pour moi de jeter un regard et appeler des méthodes sans utiliser l'API de réflexion?

a) Non, la réflexion est la seule façon de le faire

b) ne le font pas du tout. Si vous voulez une langue dynamique, utilisez Groovy. Sa syntaxe est (peut être) presque identique à Java, mais elle a déjà la plupart de cette fonctionnalité déjà intégrée. (Beaucoup d'autres langages fonctionneront aussi, mais Groovy est le plus proche de Java en comparant la syntaxe)

+0

qu'est-ce qui ne va pas w/javascript? il est même disponible en Java lui-même? – bestsss

+0

@bestsss Rien ne va pas avec JS, c'est un langage génial, et je n'ai jamais dit autrement. Mais quand vous faites une recommandation, vous devez commencer quelque part –

+0

Je n'ai jamais laissé entendre que vous avez dit quelque chose au sujet de Javascript, je me demandais juste comment ce n'est pas le premier choix. – bestsss

1

La réflexion est le seul moyen de lister les méthodes d'un objet arbitraire. Eh bien, l'analyse du bytecode fonctionne également, mais c'est fastidieux.

+0

C'est une fausse déclaration. Vous pouvez à peu près générer le code à la volée, Proxy et Reflection le font dans les coulisses. Il est possible de le faire à la main tout aussi bien. – bestsss

+0

@bestsss Quand on vous donne une instance 'Object', comment lister ses méthodes" à la main "? – Bozho

+0

@Bozho, vous obtenez sa classe (Object.getClass()) trouver la ressource de classe '(ClassLoader.getResource (className.replace ('.', '\') +". Class ")', charger la ressource, analyser le pool Constant et c'est fait ... Eh bien, il y a des librairies pour le faire (bcel par exemple), mais c'est le processus – bestsss

0

Malheureusement, il semble que la réflexion soit la seule solution. Malheureusement parce que la réflexion est non seulement plus lente, mais la programmation et le maintien est un problème. Donc, je vous suggère d'utiliser la bibliothèque apache bean util. (spécifiquement methodutils.)

1

Jetez un oeil à Apache Commons BeanUtils. C'est une excellente bibliothèque pour découvrir par programmation les méthodes et propriétés d'un objet facilement (c'est-à-dire sans écrire de code de réflexion de bas niveau). Je l'ai utilisé sur plusieurs projets. Il fournit également une API plus facile pour accéder à ces membres d'objet une fois qu'ils sont découverts. PropertyUtils et MethodUtils sont de bons endroits pour commencer.

0

Bien qu'il n'y ait aucun moyen de contourner la réflexion ici, il peut être rendu relativement indolore si vous utilisez des annotations pour marquer vos méthodes appelables. Un exemple de cette approche à l'œuvre est l'ensemble d'annotations javax.jws pour les services Web. Les idées utilisées ici peuvent être très utiles, vous pouvez définir un nom d'affichage pour chacune de vos méthodes/paramètres par exemple.

0

réflexion avec annotations fonctionne Joliment

for (Method m : interfaceClass.getMethods()) { 
     if (m.isAnnotationPresent(UIf.class)) { 
      UIf x = m.getAnnotation(UIf.class); 
      addDefinedCommand(new CommandDef(
        interfaceClass, 
        u, 
        x.name().isEmpty() ? m.getName() : x.name(), 
        x.description()) 
      ); 
     } 
}