web-dev-qa-db-ja.com

Javaのプリミティブの参照による受け渡しと同等の方法

このJavaコード:

public class XYZ {   
    public static void main(){  
        int toyNumber = 5;   
        XYZ temp = new XYZ();  
        temp.play(toyNumber);  
        System.out.println("Toy number in main " + toyNumber);  
    }

    void play(int toyNumber){  
        System.out.println("Toy number in play " + toyNumber);   
        toyNumber++;  
        System.out.println("Toy number in play after increement " + toyNumber);   
    }   
}  

これを出力します:

 
プレイ5の玩具番号
インクリメント後のプレイ中の玩具番号6 
メイン5の玩具番号

C++では、toyNumber変数を参照渡しとして渡すことができます。これにより、シャドウイングを回避できます。つまり、以下と同じ変数のコピーを作成します。

void main(){  
    int toyNumber = 5;  
    play(toyNumber);  
    cout << "Toy number in main " << toyNumber << endl;  
}

void play(int &toyNumber){  
    cout << "Toy number in play " << toyNumber << endl;   
    toyNumber++;  
    cout << "Toy number in play after increement " << toyNumber << endl;   
} 

c ++の出力は次のようになります。

プレイ中の玩具番号5 
インクリメント後のプレイ中の玩具番号6 
メイン6の玩具番号

私の質問は、C++コードと同じ出力を得るためのJavaの同等のコードは何ですか? Javaは参照渡しではなく値渡しです

104
Student

いくつかの選択肢があります。最も理にかなっているのは、あなたが何をしようとしているかに本当に依存します。

選択1:toyNumberをクラスのパブリックメンバー変数にする

class MyToy {
  public int toyNumber;
}

次に、メソッドにMyToyへの参照を渡します。

void play(MyToy toy){  
    System.out.println("Toy number in play " + toy.toyNumber);   
    toy.toyNumber++;  
    System.out.println("Toy number in play after increement " + toy.toyNumber);   
}

選択2:参照渡しではなく値を返す

int play(int toyNumber){  
    System.out.println("Toy number in play " + toyNumber);   
    toyNumber++;  
    System.out.println("Toy number in play after increement " + toyNumber);   
    return toyNumber
}

この選択では、toyNumber = temp.play(toyNumber);と読み取るために、mainの呼び出しサイトを少し変更する必要があります。

選択3:クラスまたは静的変数にする

2つの関数が同じクラスまたはクラスインスタンスのメソッドである場合、toyNumberをクラスメンバー変数に変換できます。

選択4:int型の単一要素配列を作成して渡す

これはハックと見なされますが、インラインクラス呼び出しから値を返すために時々使用されます。

void play(int [] toyNumber){  
    System.out.println("Toy number in play " + toyNumber[0]);   
    toyNumber[0]++;  
    System.out.println("Toy number in play after increement " + toyNumber[0]);   
}
167
laslowh

Javaは参照による呼び出しではありません値による呼び出しのみ

しかし、オブジェクト型の変数はすべて実際にはポインターです。

したがって、Mutable Objectを使用すると、目的の動作が表示されます

public class XYZ {

    public static void main(String[] arg) {
        StringBuilder toyNumber = new StringBuilder("5");
        play(toyNumber);
        System.out.println("Toy number in main " + toyNumber);
    }

    private static void play(StringBuilder toyNumber) {
        System.out.println("Toy number in play " + toyNumber);
        toyNumber.append(" + 1");
        System.out.println("Toy number in play after increement " + toyNumber);
    }
}

このコードの出力:

run:
Toy number in play 5
Toy number in play after increement 5 + 1
Toy number in main 5 + 1
BUILD SUCCESSFUL (total time: 0 seconds)

この動作は標準ライブラリでも確認できます。たとえば、Collections.sort(); Collections.shuffle();これらのメソッドは新しいリストを返しませんが、その引数オブ​​ジェクトを変更します。

    List<Integer> mutableList = new ArrayList<Integer>();

    mutableList.add(1);
    mutableList.add(2);
    mutableList.add(3);
    mutableList.add(4);
    mutableList.add(5);

    System.out.println(mutableList);

    Collections.shuffle(mutableList);

    System.out.println(mutableList);

    Collections.sort(mutableList);

    System.out.println(mutableList);

このコードの出力:

run:
[1, 2, 3, 4, 5]
[3, 4, 1, 5, 2]
[1, 2, 3, 4, 5]
BUILD SUCCESSFUL (total time: 0 seconds)
28
Kerem Baydoğan

作る

class PassMeByRef { public int theValue; }

次に、そのインスタンスへの参照を渡します。引数を介して状態を変更するメソッドは、特に並列コードでは回避するのが最善であることに注意してください。

18
Ingo

Javaでは参照によりプリミティブを渡すことはできません。オブジェクト型の変数はすべて実際はポインターですが、もちろん「参照」と呼ばれ、常に値によって渡されます。

参照によってプリミティブを本当に渡す必要がある状況では、人々が時々することは、パラメーターをプリミティブ型の配列として宣言し、単一要素の配列を引数として渡すことです。したがって、参照int [1]を渡し、メソッド内で配列の内容を変更できます。

10

迅速な解決策として、組み込みメソッドを使用してメソッド内の値を変更できるAtomicIntegerまたは任意のアトミック変数を使用できます。サンプルコードは次のとおりです。

import Java.util.concurrent.atomic.AtomicInteger;


public class PrimitivePassByReferenceSample {

    /**
     * @param args
     */
    public static void main(String[] args) {

        AtomicInteger myNumber = new AtomicInteger(0);
        System.out.println("MyNumber before method Call:" + myNumber.get());
        PrimitivePassByReferenceSample temp = new PrimitivePassByReferenceSample() ;
        temp.changeMyNumber(myNumber);
        System.out.println("MyNumber After method Call:" + myNumber.get());


    }

     void changeMyNumber(AtomicInteger myNumber) {
        myNumber.getAndSet(100);

    }

}

出力:

MyNumber before method Call:0

MyNumber After method Call:100
10
premSiva
public static void main(String[] args) {
    int[] toyNumber = new int[] {5};
    NewClass temp = new NewClass();
    temp.play(toyNumber);
    System.out.println("Toy number in main " + toyNumber[0]);
}

void play(int[] toyNumber){
    System.out.println("Toy number in play " + toyNumber[0]);
    toyNumber[0]++;
    System.out.println("Toy number in play after increement " + toyNumber[0]);
}
2
itun