6
votes

Comment accéder à une méthode d'un pot externe au moment de l'exécution?

Ceci est une continuation de la question postée dans: Comment charger Un fichier JAR au runtime

Je suis incertain sur la manière de continuer jusqu'au niveau d'invocation de la méthode. De mon compréhension, De l'objet Clazz, j'utilisais GetMethod ou GetDeclaredMethod pour obtenir un objet de méthode à partir de lequel j'appellerais invoke. Bien sûr, invoke nécessite une instance. Serait-ce alors ce qu'on appelle Dorun dans le code exemple?

Dois-je effectuer l'appel de la méthode Dorun.Run (), même si je souhaite exécuter une méthode différente de celle principale (en supposant qu'il est principal sur l'objet Dorun appelé avec l'invocation de l'exécution)?

Juste pour plus de clarification du post original, je demande: Dorun.run () commence un nouveau fil exécutant l'instance de l'objet de classe de type Clazz?

Merci d'avoir aidé à effacer cela pour moi.

J'ai regardé "comment-hook-go-bora-bocaux-dynamiquement-at-runtime" (désolé, n'a permis qu'un lien hypertexte), mais cela cherchait à violer la classe.NewInstance Evyness Admonition dans le premier poste que j'ai référencé .


0 commentaires

3 Réponses :


2
votes

L'exemple de code

Thread myThread = new Thread(doRun);
myThread.start();


1 commentaires

Djna - Merci pour la réponse. Malheureusement, je ne peux pas supposer que je sais rien de la classe (ES) que je puisse être chargé. J'ai un cas d'échantillon qui peut ne pas indiquer l'utilisation du monde réel. Comme il se trouve, je ne sous-classe pas, obtenez une instance du constructeur, puis utilisez GetDeclaredMethod, semblable au poste ci-dessous. Merci pour l'autre clarification, j'ai été confus sur l'invocation de la course, pensait que cela signifiait qu'un nouveau fil devait commencer - mon mauvais.



3
votes

Voici un code de réflexion qui ne se déclenche pas vers une interface: xxx

écriture des classes réfléchies à une interface connue par le code de consommateur ( dans l'exemple ) est généralement meilleur car il vous permet d'éviter la réflexion et de prendre avantage du système de type Java. La réflexion ne doit être utilisée que lorsque vous n'avez pas d'autre choix.


5 commentaires

Donc, si je comprends votre commentaire après le code, avec une interface, je sais quelles méthodes sont disponibles et que vous pouvez écrire du code appelant la méthode directement après la mise en place de l'objet d'instance de manière appropriée. Est-ce vrai?


Bien sûr, cela suppose que le code d'origine avait été compilé à l'aide de l'interface, pas une fois que je crée plus tard et tente de lancer l'instance.


@Todd - Oui, vous l'avez. L'interface (ou une autre mise en œuvre de type forte) est souvent utilisée avec des plugins où le code a été écrit pour être instancié de manière dynamique. Si vous faites une introspection et une invocation sur des classes arbitraires, ce n'est pas une option.


@Mcdowell - J'ai échoué dans ma variante de votre code. J'ai ajouté la méthode suivante: Public Void Impression2 (chaîne [] Strings) {pour (chaîne finale String: Strings) {System.out.println (String); }} Avec ce qui suit dans la méthode principale: Méthode print2 = Clazz.GetDeclaredMethod ("print2", nouvelle classe [] {string []. Classe}); print2.invoke (instance, nouvelle chaîne [] {"Test1", "Test2"}); Il en résulte: Exception dans le fil "Main" Java.lang.illegalargumentException: mauvais nombre d'arguments Avez-vous des idées?


Ce dernier message est trop salissant pour lire, je vais générer un nouveau post.



1
votes

exemple de programme:

Imprimante de projet: P>

       URL url = new URL("file:Printer.jar"); 
       URLClassLoader loader = new URLClassLoader (new URL[] {url});
       Class<?> cl = Class.forName ("Printer", true, loader);
       String printString = "Print this";
       Method printit = cl.getMethod("display", String.class);
       Constructor<?> ctor = cl.getConstructor(); //One has to pass arguments if constructor takes input arguments.
       Object instance = ctor.newInstance();
       printit.invoke(instance, printString);
       loader.close ();


0 commentaires