web-dev-qa-db-fra.com

Comment utiliser un paramètre de sortie en Java?

Quelqu'un pourrait-il me donner un exemple de code utilisant un paramètre de sortie dans function? J'ai essayé de le rechercher sur Google, mais je l'ai trouvé uniquement dans les fonctions. J'aimerais utiliser cette valeur de sortie dans une autre fonction.

Le code que je développe est destiné à être exécuté sur Android. 

59
soclose

Java passe par valeur; il n'y a pas de paramètre out comme en C #.

Vous pouvez utiliser return ou muter un objet passé en tant que une référence (valeur par).

Questions connexes


Échantillon de code

public class FunctionSample {
    static String fReturn() {
        return "Hello!";
    }
    static void fArgNoWorkie(String s) {
        s = "What am I doing???"; // Doesn't "work"! Java passes by value!
    }
    static void fMutate(StringBuilder sb) {
        sb.append("Here you go!");
    }
    public static void main(String[] args) {
        String s = null;

        s = fReturn();
        System.out.println(s); // prints "Hello!"

        fArgNoWorkie(s);
        System.out.println(s); // prints "Hello!"

        StringBuilder sb = new StringBuilder();
        fMutate(sb);
        s = sb.toString();
        System.out.println(s); // prints "Here you go!"
    }

}

Voir également


En ce qui concerne le code avec lequel OP a besoin d'aide, voici une solution classique consistant à utiliser une valeur spéciale (généralement null pour les types de référence) pour indiquer le succès/l'échec:

Au lieu de:

String oPerson= null;
if (CheckAddress("5556", oPerson)) {
   print(oPerson); // DOESN'T "WORK"! Java passes by value; String is immutable!
}

private boolean CheckAddress(String iAddress, String oPerson) {
   // on search succeeded:
   oPerson = something; // DOESN'T "WORK"!
   return true;
   :
   // on search failed:
   return false;
}

Utilisez plutôt un type de retour String, avec null pour indiquer un échec.

String person = checkAddress("5556");
if (person != null) {
   print(person);
}

private String checkAddress(String address) {
   // on search succeeded:
   return something;
   :
   // on search failed:
   return null;
}

C'est ainsi que (Java.io.BufferedReader.readLine() } _ _ fonctionne, par exemple: il renvoie instanceof String (peut-être une chaîne vide!), Jusqu'à ce qu'il retourne null pour indiquer la fin de "recherche".

Ceci n'est évidemment pas limité à une valeur de retour de type référence. La clé est qu'il doit y avoir une valeur spéciale qui n'est jamais une valeur valide et que vous utilisez cette valeur à des fins spéciales.

Un autre exemple classique est String.indexOf : il renvoie -1 pour indiquer un échec de la recherche.

Remarque: Java ne connaissant pas les paramètres "d'entrée" et "de sortie", l'utilisation des préfixes i- et o- (par exemple, iAddress, oPerson) est inutile et non automatique.


Une solution plus générale

Si vous devez renvoyer plusieurs valeurs, elles sont généralement liées d'une manière ou d'une autre (par exemple, les coordonnées x et y d'un seul Point). La meilleure solution serait d'encapsuler ces valeurs ensemble. Les gens ont utilisé un Object[] ou un List<Object>, ou un Pair<T1,T2> générique, mais en réalité, votre propre type serait préférable.

Pour ce problème, je recommande un type SearchResult immuable comme celui-ci pour encapsuler les résultats de la recherche boolean et String:

public class SearchResult {
   public final String name;
   public final boolean isFound;

   public SearchResult(String name, boolean isFound) {
      this.name = name;
      this.isFound = isFound;
   }
}

Ensuite, dans votre fonction de recherche, vous procédez comme suit:

private SearchResult checkAddress(String address) {
  // on address search succeed
  return new SearchResult(foundName, true);
  :
  // on address search failed
  return new SearchResult(null, false);
}

Et puis vous l'utilisez comme ceci:

SearchResult sr = checkAddress("5556");
if (sr.isFound) {
  String name = sr.name;
  //...
}

Si vous le souhaitez, vous pouvez (et devriez probablement) créer les champs final immuables non -public et utiliser plutôt les gettres public.

104

Java ne prend pas en charge les paramètres de sortie. Vous pouvez utiliser une valeur de retour ou transmettre un objet en tant que paramètre et le modifier.

6
SingleShot

Pour contourner le problème, un "ObjectHolder" générique peut être utilisé. Voir exemple de code ci-dessous. 

L'exemple de sortie est:

name: John Doe
dob:1953-12-17
name: Jim Miller
dob:1947-04-18

le paramètre Person a donc été modifié puisqu'il est encapsulé dans le titulaire, lequel est passé par valeur (le paramètre générique à l'intérieur est une référence permettant de modifier le contenu). Ainsi, une personne différente est renvoyée et l'original reste en l'état.

/**
 * show work around for missing call by reference in Java
 */
public class OutparamTest {

 /**
  * a test class to be used as parameter
  */
 public static class Person {
   public String name;
     public String dob;
     public void show() {
      System.out.println("name: "+name+"\ndob:"+dob);
   }
 }

 /**
  * ObjectHolder (Generic ParameterWrapper)
  */
 public static class ObjectHolder<T> {
    public ObjectHolder(T param) {
     this.param=param;
    }
    public T param;
 }

 /**
  * ObjectHolder is substitute for missing "out" parameter
  */
 public static void setPersonData(ObjectHolder<Person> personHolder,String name,String dob) {
    // Holder needs to be dereferenced to get access to content
    personHolder.param=new Person();
    personHolder.param.name=name;
    personHolder.param.dob=dob;
 } 

  /**
   * show how it works
   */
  public static void main(String args[]) {
    Person jim=new Person();
    jim.name="Jim Miller";
    jim.dob="1947-04-18";
    ObjectHolder<Person> testPersonHolder=new ObjectHolder(jim);
    // modify the testPersonHolder person content by actually creating and returning
    // a new Person in the "out parameter"
    setPersonData(testPersonHolder,"John Doe","1953-12-17");
    testPersonHolder.param.show();
    jim.show();
  }
}
5
Wolfgang Fahl

Vous pouvez soit utiliser:

  • renvoyer X. cela ne renverra qu'une valeur. 

  • retourne un objet. retournera un objet complet. Par exemple, votre objet peut inclure des valeurs X, Y et Z.

  • passer tableau. les tableaux sont passés par référence. c'est-à-dire que si vous passez un tableau d'entiers, modifié le tableau à l'intérieur de la méthode, le code d'origine verra les modifications.

Exemple en passant Array.

void methodOne{
    int [] arr = {1,2,3};
    methodTwo(arr);
    ...//print arr here
}
void methodTwo(int [] arr){
    for (int i=0; i<arr.length;i++){
         arr[i]+=3;
    }
}

Ceci imprimera: 4,5,6.

4
medopal

Enveloppez la valeur passée dans différentes classes qui pourraient être utiles, vérifiez ci-dessous pour obtenir un exemple plus réel: 

  class Ref<T>{

    T s;

    public void set(T value){
        s =  value;
    }

    public T get(){
        return s;
    }

    public Ref(T value) {
        s = value;
    }
}


class Out<T>{

    T s;

    public void set(T value){
        s =  value;
    }
    public T get(){
        return s;
    }

    public Out() {
    }
}

public static void doAndChangeRefs (Ref<String> str, Ref<Integer> i, Out<String> str2){
    //refs passed .. set value
    str.set("def");
    i.set(10);

    //out param passed as null .. instantiate and set 
    str2 = new Out<String>();
    str2.set("hello world");
}
public static void main(String args[]) {
        Ref<Integer>  iRef = new Ref<Integer>(11);
        Out<String> strOut = null; 
        doAndChangeRefs(new Ref<String>("test"), iRef, strOut);
        System.out.println(iRef.get());
        System.out.println(strOut.get());

    }
3
msoliman

Ceci n’est pas exact ---> "... ... tableau de passes. Les tableaux sont passés par référence. Par exemple, si vous passez un tableau d’entiers, modifiez le tableau dans la méthode.

Chaque type de paramètre est passé par valeur en Java. Les tableaux sont object, sa référence d'objet est passée par valeur.

Cela inclut un tableau de primitives (int, double, ..) et d'objets. Le nombre entier valeur est modifié par la méthode methodTwo () mais reste la même référence d'objet arr, la méthodeTwo () ne peut pas ajouter d'élément de tableau ni supprimer un élément de tableau. methodTwo () ne peut pas non plus, créer un nouveau tableau, puis définir ce nouveau tableau sur arr. Si vous pouvez réellement passer un tableau par référence, vous pouvez remplacer cet arr par un nouveau tableau d'entiers.

Chaque objet passé comme paramètre en Java est passé par valeur, sans exception.

1
edvox1138

Je vous remercie. J'utilise le passage dans un objet en tant que paramètre. Mon code Android est ci-dessous

    String oPerson= null;
    if (CheckAddress("5556", oPerson))
    {
        Toast.makeText(this, 
                "It's Match! " + oPerson,                   
                Toast.LENGTH_LONG).show();
    }

    private boolean CheckAddress(String iAddress, String oPerson)
{
    Cursor cAddress = mDbHelper.getAllContacts();
    String address = "";        
    if (cAddress.getCount() > 0) {
        cAddress.moveToFirst();
        while (cAddress.isAfterLast() == false) {
            address = cAddress.getString(2).toString();
            oPerson = cAddress.getString(1).toString(); 
            if(iAddress.indexOf(address) != -1)
            {
                Toast.makeText(this, 
                        "Person : " + oPerson,                  
                        Toast.LENGTH_LONG).show();
                System.out.println(oPerson);
                cAddress.close();
                return true;                    
            }
            else cAddress.moveToNext();
        }
    }
    cAddress.close();
    return false;
}

Le résultat est

Personne: John

C'est match! nul

En fait, "c'est un match! John"

S'il vous plaît vérifier mon erreur.

0
soclose