JAVA中値転送と参照転送

4315 ワード

前言
Javaのデータ型は、基本データ型と参照データ型に分けられることはよく知られています.
  • 基本データ型
  • 整型:byte,short,int,long
  • 浮動小数点型:float,double
  • 文字型:char
  • ブール型:boolean
  • 参照データ型
  • 配列
  • クラス
  • インタフェース

  • メソッドのパラメータは、実際のパラメータと形式パラメータに分けられます.
  • 形式パラメータ:メソッドの定義時に書かれたパラメータ
  • 実際のパラメータ:メソッドを呼び出すときに書かれた具体的な数値
  • 一般に、データがパラメータとして渡される場合、基本データ型は値伝達、参照データ型は参照伝達(アドレス伝達)
    値の転送
    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 20;
    
        swap(num1, num2);
    
        System.out.println("num1 = " + num1);
        System.out.println("num2 = " + num2);
    }
    
    public static void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
    
        System.out.println("a = " + a);
        System.out.println("b = " + b);
    }
    

    実行結果は次のとおりです.
    a = 20
    b = 10
    num1 = 10
    num2 = 20
    

    プロセス:
  • 主関数スタック、num 1、num 2初期化.
  • はswapメソッドを呼び出し、swap()はスタックに入り、num 1とnum 2の値をaとbにコピーする.
  • swapメソッドではa,bの値を交換する.
  • swapメソッドの実行が完了し、a、bの値が交換されました.
  • swapメソッドスタック.
  • 主関数スタック.

  • 解析:
    swap法では,a,bの値を交換し,num 1,num 2に影響を及ぼさない.なぜなら、a、bの値は、num 1、num 2のコピーからしかコピーされていないからです.すなわち,a,bはnum 1,num 2のコピーに相当し,コピーの内容がどのように修正されてもオリジナルそのものには影響しない.
    リファレンス転送
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
    
        change(arr);
    
        System.out.println(arr[0]);
    }
    
    //           0
    public static void change(int[] array) {
        int len = array.length;
        array[0] = 0;
    }
    

    実行結果は次のとおりです.
    0
    

    プロセス:
  • 主関数スタック、int[]arr初期化.
  • changeメソッドを呼び出し、change()をスタックに入れ、arrのアドレス値をarrayにコピーします.
  • changeメソッドでは、アドレス値に基づいてスタック内の配列を見つけ、最初の要素の値を0に変更します.
  • changeメソッドが実行され、配列内の最初の要素の値が変更されました.
  • changeメソッド弾桟.
  • 主関数スタック.

  • 解析:
    change()を呼び出すと,パラメータarrayはarrアドレス値のコピーを受信する.そしてchangeメソッドでは,アドレス値により配列を操作する.changeメソッドスタック以降、配列の値が変更されました.mainメソッドでは、印刷されたarr[0]も元の1から0に変わります.
    プライマリ関数でもchangeメソッドでも、同じアドレス値に対応する配列が動作します.あなたが自分の家の鍵を別の人にあげたように、この人は鍵を持ってあなたの家ででたらめを言って、それから行きました.あなたが鍵を持って家に帰った後、家はもう振り回された後、見るに忍びない様子になりました.ここの鍵はアドレス値に相当し,家は配列そのものに相当する.
    Stringタイプ転送
    
    public static void main(String[] args) {
        String str = "AAA";
    
        change(str);
    
        System.out.println(str);
    }   
    public static void change(String s) {
        s = "abc";
    }
    

    実行結果は次のとおりです.
    AAA
    

    Stringはクラスであり、クラスは参照データ型であり、パラメータとして渡す場合は参照伝達であるべきである.結果から見れば値伝達
    理由:
    StringのAPIには「their values cannot be changed after they are created」という言葉があります.Stringの値は作成後は変更できません.APIにはもう1つのセグメントがあります:String str=“abc”;等価:char data[]={'a','b','c'};String str = new String(data); すなわち、Stringオブジェクトstrに対する変更は、オブジェクトを再作成し、strに新しいアドレス値を割り当てることに等しい.
    これで、上のコードは次のように書くことができます.
    public static void main(String[] args) {
        String str1 = "AAA";
    
        change(str1);
    
        System.out.println(str1);
    }   
    public static void change(String s) {
        char data[] = {'a', 'b', 'c'}
        String str = new String(data);
        s = str;
    }
    
    

    プロセス:
  • 主関数スタック、str 1初期化.
  • はchangeメソッドを呼び出し、change()はスタックに入り、str 1のアドレス値をsにコピーする.
  • changeメソッドでは、Stringオブジェクト「abc」が作成され、sが新しいアドレス値に指し示されます.
  • changeメソッドの実行が完了し、sが指すアドレス値が変更されました.
  • changeメソッド弾桟.
  • 主関数スタック.

  • 解析:
    Stringオブジェクトがパラメータとして渡される場合、歩いているのは依然として参照伝達ですが、Stringというクラスは特殊です.Stringオブジェクトが作成されると、内容は変更できません.コンテンツの変更のたびに、作成された新しいオブジェクトが再現されます.changeメソッドの実行が完了すると、sが指すアドレス値が変更される.s本来のアドレス値はcopyからのコピーであるためstr 1の値を変えることはできない.
    Stringタイプ類似:
    class Person {
        String name;
    
        public Person(String name) {
            this.name = name;
        }
    }
    public class Test {
        public static void main(String[] args) {
            Person p = new Person("  ");
    
            change(p);
    
            System.out.println(p.name);
        }
    
        public static void change(Person p) {
            Person person = new Person("  ");
            p = person; 
        }
    }
    

    実行結果は次のとおりです.
      
    

    まとめ
  • 値が渡されると、実パラメータの値、copyを形パラメータに1部与えます.
  • 参照が渡されると、実パラメータのアドレス値、copyが形パラメータに1部与えられます.

  • すなわち,値伝達であろうと参照伝達であろうと,パラメータは実パラメータそのものではなく実パラメータのコピーを取得するだけである.