Как использовать выходной параметр в Java? - PullRequest
59 голосов
/ 13 мая 2010

Может кто-нибудь дать мне пример кода, который использует выходной параметр функции? Я пытался Google, но только что нашел его в функциях. Я хотел бы использовать это выходное значение в другой функции.

Код, который я разрабатываю, предназначен для запуска в Android.

Ответы [ 7 ]

104 голосов
/ 13 мая 2010

Java проходит по значению; нет параметра out, как в C #.

Вы можете использовать return или изменить объект, переданный как ссылку ( по значению).

Похожие вопросы


Пример кода

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!"
    }

}

Смотри также


Что касается кода , с которым OP требуется помощь, вот типичное решение использования специального значения (обычно null для ссылочных типов) для указания успеха / неудачи:

Вместо:

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;
}

Вместо этого используйте тип возврата String, с null для обозначения ошибки.

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

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

Так работает, например, java.io.BufferedReader.readLine(): он возвращает instanceof String (возможно, пустую строку!), Пока не вернет null, чтобы указать конец «поиска».

Конечно, это не ограничивается возвращаемым значением ссылочного типа. Ключ в том, что должно быть какое-то специальное значение (я), которое никогда не является допустимым значением, и вы используете это значение для специальных целей.

Другой классический пример: String.indexOf: он возвращает -1, чтобы указать на ошибку поиска.

Примечание : поскольку в Java нет понятия параметров «ввода» и «вывода», используется префикс i- и o- (например, iAddress, oPerson) ненужный и однотипный.


Более общее решение

Если вам нужно вернуть несколько значений, обычно они связаны каким-либо образом (например, x и y координаты одного Point). Лучшим решением было бы объединить эти значения вместе. Люди использовали Object[] или List<Object>, или универсальный Pair<T1,T2>, но на самом деле ваш собственный тип был бы лучшим.

Для этой проблемы я рекомендую неизменный тип SearchResult, подобный этому, для инкапсуляции результатов поиска boolean и String:

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

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

Затем в функции поиска вы делаете следующее:

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

А потом вы используете это так:

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

Если вы хотите, вы можете (и, вероятно, должны) сделать final неизменяемые поля не public и использовать вместо них public getter.

6 голосов
/ 13 мая 2010

Java не поддерживает выходные параметры. Вы можете использовать возвращаемое значение или передать объект в качестве параметра и изменить объект.

5 голосов
/ 17 декабря 2012

В качестве обходного пути можно использовать универсальный «ObjectHolder». Смотрите пример кода ниже.

Пример вывода:

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

поэтому параметр Person был изменен, поскольку он обернут в Holder, который передается по значению - общий параметр внутри является ссылкой, где содержимое может быть изменено - так что фактически возвращается другой человек, а оригинал остается как есть.

/**
 * 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();
  }
}
4 голосов
/ 13 мая 2010

Вы можете использовать:

  • вернуть X. это вернет только одно значение.

  • возврат объекта. вернет полный объект. Например, ваш объект может содержать значения X, Y и Z.

  • проходной массив. массивы передаются по ссылке. то есть, если вы передадите массив целых чисел, изменив массив внутри метода, то исходный код увидит изменения.

Пример прохождения массива.

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;
    }
}

Это распечатает: 4,5,6.

3 голосов
/ 02 декабря 2015

Оберните значение, передаваемое в разные классы, которые могут быть полезны при выполнении трюка, проверьте более реальный пример ниже:

  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());

    }
1 голос
/ 23 апреля 2011

Это не точно ---> "... * передать массив. Массивы передаются по ссылке. То есть, если вы передаете массив целых чисел, измените массив внутри метода.

Каждый тип параметра передается по значению в Java. Массивы являются объектом, его ссылка на объект передается по значению.

Сюда входит массив примитивов (int, double, ..) и объектов. Целое число значение изменяется методом methodTwo (), но это все та же ссылка на объект arr, methodTwo () не может добавить элемент массива или удалить элемент массива. methodTwo () также не может создать новый массив, затем установить для этого нового массива значение arr. Если вы действительно можете передать массив по ссылке, вы можете заменить этот массив новым массивом целых чисел.

Каждый объект, передаваемый как параметр в Java, передается по значению, без исключений.

0 голосов
/ 13 мая 2010

Спасибо. Я использую передачу объекта в качестве параметра. Мой код Android ниже

    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;
}

Результат

Персона: Джон

Это матч! нуль

На самом деле, "Это соответствует! Джон"

Пожалуйста, проверьте мою ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...