web-dev-qa-db-fra.com

Existe-t-il un moyen de prendre un argument dans une méthode appelable?

J'ai créé un morceau de code qui prend une adresse IP (à partir de la méthode principale dans une autre classe), puis fait une boucle à travers une plage d'adresses IP qui cinglent chacune au fur et à mesure. J'ai une interface graphique à ce sujet et il plantait (d'où la raison pour laquelle j'ai fait le multithreading. Mon problème est que je ne peux plus prendre l'adresse IP comme argument dans mon code ping comme appelable. J'ai cherché partout pour cela et je ne peux pas trouver un moyen de contourner ce problème. Existe-t-il un moyen pour une méthode appelable de prendre des arguments? Sinon, existe-t-il un autre moyen d'accomplir ce que j'essaie de faire?

exemple de mon code:

public class doPing implements Callable<String>{

public String call() throws Exception{

    String pingOutput = null;

    //gets IP address and places into new IP object
    InetAddress IPAddress = InetAddress.getByName(IPtoPing);
    //finds if IP is reachable or not. a timeout timer of 3000 milliseconds is set.
    //Results can vary depending on permissions so cmd method of doing this has also been added as backup
    boolean reachable = IPAddress.isReachable(1400);

    if (reachable){
          pingOutput = IPtoPing + " is reachable.\n";
    }else{
        //runs ping command once on the IP address in CMD
        Process ping = Runtime.getRuntime().exec("ping " + IPtoPing + " -n 1 -w 300");
        //reads input from command line
        BufferedReader in = new BufferedReader(new InputStreamReader(ping.getInputStream()));
        String line;
        int lineCount = 0;
        while ((line = in.readLine()) != null) {
            //increase line count to find part of command Prompt output that we want
            lineCount++;
            //when line count is 3 print result
            if (lineCount == 3){
                pingOutput = "Ping to " + IPtoPing + ": " + line + "\n";
            }
        }
    }
    return pingOutput;
}
}

IPtoPing était l'argument utilisé.

37
DMo

Vous ne pouvez pas le passer comme argument à call() car la signature de la méthode ne le permet pas.

Cependant, vous pouvez le passer comme argument constructeur; par exemple.

public class DoPing implements Callable<String>{
    private final String ipToPing;

    public DoPing(String ipToPing) {
        this.ipToPing = ipToPing;
    }

    public String call() throws SomeException {
        InetAddress ipAddress = InetAddress.getByName(ipToPing);
        ....
    }
}

(J'ai corrigé quelques violations flagrantes du style de code !!)

Vous pouvez également:

  • déclarer DoPing en tant que classe interne et le faire référence à un final ipToPing dans la portée englobante, ou

  • ajoutez une méthode setIpToPing(String ipToPing).

(Le dernier permet de réutiliser un objet DoPing, mais l'inconvénient est que vous devrez vous synchroniser pour y accéder en toute sécurité.)

49
Stephen C

Ajout à la réponse de Jarle - dans le cas où vous créez Callable comme instance de classe anonyme, vous pouvez utiliser le champ final en dehors de la classe anonyme pour passer des données dans l'instance:

    final int arg = 64;
    executor.submit(new Callable<Integer>() {
        public Integer call() throws Exception {
            return arg * 2;
        }
    });
7
Victor Sorokin

Lorsque vous créez la classe doPing (qui doit être en majuscule dans le nom de la classe), envoyez l'adresse IP dans le constructeur. Utilisez cette adresse IP dans la méthode d'appel.

5
Jarle Hansen

Vous ne pouvez pas passer d'arguments à call() parce que la signature de la méthode ne le permet pas mais voici au moins une façon de contourner cela en

  1. définir une classe abstraite qui enveloppe/implémente Callable et
  2. implémenter un setter pour "injecter" un résultat dans call()

Définissez une classe abstraite:

import Java.util.concurrent.Callable;

public abstract class Callback<T> implements Callable<Void> {
    T result;

    void setResult (T result) {
        this.result = result;
    }

    public abstract Void call ();
}

Définissez la méthode qui doit déclencher le rappel:

public void iWillFireTheCallback (Callback callback) {
    // You could also specify the signature like so:
    // Callback<Type of result> callback

    // make some information ("the result")
    // available to the callback function:
    callback.setResult("Some result");

    // fire the callback:
    callback.call();
}

À l'endroit où vous souhaitez appeler iWillFireTheCallback:

Définissez la fonction de rappel (même possible à l'intérieur des méthodes):

class MyCallback extends Callback {
    @Override
    public Void call () {
        // this is the actual callback function

        // the result variable is available right away:
        Log.d("Callback", "The result is: " + result);

        return null;
    }
}

Et puis appelez iWillFireTheCallback en passant le rappel:

iWillFireTheCallback(new MyCallback());
5
Per

Mettez quelques champs (final) dans votre classe doPing et un constructeur qui les initialise, puis passez les valeurs que vous souhaitez utiliser dans call() au constructeur de doPing:

public class doPing implements Callable<String>  {
     private final String ipToPing;

     public doPing(String ip) {
         this.ipToPing = ip;
     }

     public String call() {
         // use ipToPing
     }
}
3
daveb

Vous devez définir une propriété telle que ipAddress et sa méthode d'accesseur. et en passant sa valeur dans constructor ou par la méthode setter. Dans la classe doPing, utilisez la propriété ipAddress.

class DoPing/* In Java all classes start with capital letter */implements Callable<String>
{
    private String  ipAddress;

    public String getIpAddress()
    {
        return ipAddress;
    }

    public void setIpAddress(String ipAddress)
    {
        this.ipAddress = ipAddress;
    }

    /*
     * Counstructor 
     */
    public DoPing(String ipAddress )
    {
        this.ipAddress = ipAddress;
    }

    @Override
    public String call() throws Exception
    {
        // your logic
    }
}
1
Sam