函式中引數傳值

lovekey 發表於 2022-06-15

函式中引數傳值

1、基本資料型別傳值

當函式中傳入的引數為基本資料型別時,函式中對傳入引數的操作不會對函式外的資料產生影響。由於基本資料型別的變數名指向的是具體的數值,在函式內部,相當於將引數進行了拷貝,函式內只對拷貝後的引數進行操作。

  • 基本資料型別
public class ParamsTrans {
    /**
     * 基本資料型別傳值
     * @param a 基本資料型別
     */
    private static void primitiveType(int a){
        a = 1;
    }

    public static void main(String[] args) {
        int primitiveParam = 0;
        ParamsTrans.primitiveType(primitiveParam);
        System.out.println(primitiveParam);
    }
}

// 結果:0

結果分析:基本資料型別primitiveParam初始值為0,在函式中對其值進行修改,輸出值仍為0,說明函式內的操作未生效。

  • 基本資料型別陣列
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ParamsTrans {
    /**
     * 基本資料型別陣列傳值
     * @param d
     */
    private static void arrayType(int[] d){
        d[0] = 1;
        System.out.println("d hashcode:" + d.hashCode());
    }

    public static void main(String[] args) {
        int[] arrayParam = new int[2];
        arrayType(arrayParam);
        System.out.println(Arrays.toString(arrayParam));
        System.out.println("arrayParam hashcode:" + arrayParam.hashCode());
    }
}


// 結果:
// d hashcode:460141958
// [1, 0]
// arrayParam hashcode:460141958

結果分析:基本資料型別陣列與基本資料型別在引數傳值時,具有相同特性。

2、引用資料型別傳值

當函式中傳入的引數為引用資料型別時,函式中對傳入引數的操作會對函式外的資料產生影響。由於引用變數指向物件的記憶體地址,在函式內部,引數只是建立了一個新的變數指向同一個物件,函式中對此物件進行操作,函式外的引用變數也會相應改變。

import java.util.ArrayList;
import java.util.List;

public class ParamsTrans {
    /**
     * 引用資料型別傳值
     * @param b 引用資料型別
     */
    private static void QuoteType(List<Integer> b){
        b.add(1);
        System.out.println("b hashcode:" + b.hashCode());
    }

    public static void main(String[] args) {
        List<Integer> quoteParam = new ArrayList<>();
        ParamsTrans.QuoteType(quoteParam);
        System.out.println(quoteParam.toString());
        System.out.println("quoteParam hashcode:" + quoteParam.hashCode());
    }
}

// 結果:
// b hashcode:32
// [1]
// quoteParam hashcode:32

結果分析:引用資料型別quoteParam初始值為空,在函式中新增元素,輸出值為[1],說明函式內的操作已生效。由變數hash值可以看出,函式內與函式外為同一變數。

3、包裝資料型別傳值

在Java中,有一些對基本資料型別進行包裝的型別,在引數傳值時比較容易混淆,如:String、Integer、Double等。

  • String型別

    public class ParamsTrans {
        /**
         * Sting型別傳值
         * @param c
         */
        private static void StringType(String c){
            c = "b";
            System.out.println("c hashcode:" + c.hashCode());
        }
    
        public static void main(String[] args) {
            String stringParam = "a";
            StringType(stringParam);
            System.out.println(stringParam);
            System.out.println("stringParam hashcode:" + stringParam.hashCode());
        }
    }
    
    // 結果:
    // c hashcode:98
    // a
    // stringParam hashcode:97
    

    結果分析:由程式碼執行結果可以看出,String型別雖然是引用變數,但是在函式中對其進行修改的操作並未生效,且函式內與函式外的變數也並不是同一個變數。這不符合上述引用資料型別的規律,由String型別原始碼可知,String中字串實際是用char[]陣列進行儲存的,相當於是char[]的包裝類。因此,在引數傳遞時,是對引數進行了拷貝。

  • Integer型別及包裝型別

    根據上述對String型別的分析,檢視Integer類原始碼,對Integer類進行賦值實際是對int型別進行操作。綜上所述,在函式引數傳值時,Integer與String具有相同特性。再推廣至包裝型別,所有包裝型別均具有此特性。

相關文章