web-dev-qa-db-ja.com

Javaで出力パラメーターを使用する方法は?

関数で出力パラメーターを使用するサンプルコードを教えてください。 Googleで試してみましたが、機能だけで見つけました。この出力値を別の関数で使用したいと思います。

私が開発しているコードは、Androidで実行することを意図しています。

59
soclose

Javaは値を渡します。 C#のようなoutパラメーターはありません。

returnを使用するか、参照としてとして渡されたオブジェクトを変更できます()(by値)。

関連する質問


コードサンプル

_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が支援を必要とする code に関しては、成功/失敗を示すために特別な値(通常は参照型の場合は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() の仕組みです。たとえば、nullが返されて終了を示すまで、_instanceof String_(おそらく空の文字列!)を返します。 "調べる"。

もちろん、これは参照型の戻り値に限定されません。重要な点は、決して有効な値ではない特別な値が必要であり、その値を特別な目的に使用することです。

もう1つの典型的な例は _String.indexOf_ です。これは、検索失敗を示す_-1_を返します。

:なぜなら、Javaには、接頭辞_i-_および_o-_を使用する「入力」および「出力」パラメーターの概念がないためです。 (たとえば、iAddressoPerson)は不要であり、一義的です。


より一般的なソリューション

複数の値を返す必要がある場合、通常は何らかの方法で関連付けられています(例:単一のxyおよびPoint座標)。最良の解決策は、これらの値を一緒にカプセル化することです。人々は_Object[]_または_List<Object>_、または汎用_Pair<T1,T2>_を使用しましたが、実際には、独自の型が最適です。

この問題では、SearchResultbooleanの検索結果をカプセル化するために、このような不変の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ゲッターを使用できます(おそらくそうすべきです)。

105

Javaは出力パラメーターをサポートしていません。戻り値を使用するか、オブジェクトをパラメーターとして渡し、オブジェクトを変更できます。

6
SingleShot

回避策として、汎用の「ObjectHolder」を使用できます。以下のコード例を参照してください。

サンプル出力は次のとおりです。

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

そのため、値によって渡されるHolderにラップされているため、Personパラメーターが変更されています-内部の一般的なパラメーターは、コンテンツを変更できる参照です-実際には、別の人が返され、元のままです。

/**
 * 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

次のいずれかを使用できます。

  • xを返します。これは1つの値のみを返します。

  • オブジェクトを返します。完全なオブジェクトを返します。たとえば、オブジェクトには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が出力されます。

4
medopal

トリックを行うのに役立つ可能性のあるさまざまなクラスに渡された値をラップします。より実際の例については以下を確認してください。

  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

これは正確ではありません---> "... *配列を渡します。配列は参照渡しされます。つまり、整数の配列を渡す場合は、メソッド内の配列を変更します。

すべてのパラメータータイプは、Javaで値によって渡されます。配列はオブジェクトであり、そのオブジェクト参照は値で渡されます。

これには、プリミティブ(int、double、..)およびオブジェクトの配列が含まれます。整数はmethodTwo()によって変更されますが、同じarrオブジェクト参照であるため、methodTwo()は配列要素を追加したり、配列要素を削除したりできません。 methodTwo()は、新しい配列を作成してから、この新しい配列をarrに設定することもできません。本当に参照渡しで配列を渡すことができる場合は、そのarrを新しい整数の配列に置き換えることができます。

Javaのパラメーターとして渡されるすべてのオブジェクトは、例外なしで値によって渡されます。

1
edvox1138

ありがとうございました。パラメータとしてオブジェクトを渡すことを使用します。私の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;
}

結果は

人:ジョン

マッチです!ヌル

実際、「それはマッチです!ジョン」

私の間違いをチェックしてください。

0
soclose