深刻解析Java編程中辦法的參數傳遞。本站提示廣大學習愛好者:(深刻解析Java編程中辦法的參數傳遞)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻解析Java編程中辦法的參數傳遞正文
在浏覽本文之前,依據本身的經歷和懂得,年夜家可以先思慮並選擇一下Java函數的參數傳遞方法:
A. 是按值傳遞的?
B. 按援用傳遞的?
C. 部門按值部門按援用?
此處暫不宣告准確謎底,我們經由過程一個簡略的例子讓年夜家本身找謎底:
1. 先界說一個類型Value
public static class Value { private String value = "value"; public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
2. 寫兩個函數newValue和modifyValue:newValue會將入參指向一個新的對象,modifyValue會挪用入參的setValue辦法修正對象的value值。
public static void newValue(Value value) { value = new Value(); value.setValue("new value"); System.out.println("In newValue, HashCode = " + value.hashCode() + ", value = " + value.getValue()); } public static void modifyValue(Value value) { value.setValue("new value"); System.out.println("In modifyValue, HashCode = " + value.hashCode() + ", value = " + value.getValue()); }
3. 簡略的測試代碼
public static void main(String[] args) { Value value1 = new Value(); System.out.println("Before modify, HashCode = " + value1.hashCode() + ", value = " + value1.getValue()); // 將value1指向新的Value對象 newValue(value1); System.out.println("After modify, HashCode = " + value1.hashCode() + ", value = " + value1.getValue() + "\n"); Value value2 = new Value(); System.out.println("Before modify, HashCode = " + value2.hashCode() + ", value = " + value2.getValue()); // 應用object的set辦法,修正對象的外部值 modifyValue(value2); System.out.println("After modify, HashCode = " + value2.hashCode() + ", value = " + value2.getValue()); }
4. 履行成果日記:
Before modify, HashCode = 12677476, value = value In newValue, HashCode = 33263331, value = new value After modify, HashCode = 12677476, value = value Before modify, HashCode = 6413875, value = value In modifyValue, HashCode = 6413875, value = new value After modify, HashCode = 6413875, value = new value
5. 成果剖析:
上述代碼這長短經常見的一種編程形式:在核心界說|保留|獲得一個值或對象,將這個對象作為參數傳入一個辦法,在辦法中修正對象的屬性、行動。但兩個辦法newValue和modifyValue的修正方法紛歧樣,在辦法挪用以後,該對象在核心看來也有很年夜的差異!若何懂得這類差別呢?先溫故一下按值傳遞、按援用傳遞的概念:
* 按值傳遞意味著當將一個參數傳遞給一個函數時,函數吸收的是原始值的一個正本。是以,假如函數修正了該參數,僅轉變正本,而原始值堅持不變。
* 按援用傳遞意味著當將一個參數傳遞給一個函數時,函數吸收的是原始值的內存地址,而不是值的正本。是以,假如函數修正了該參數,參數的原始值(函數塊以外的挪用代碼中)也隨之轉變。
准確的謎底:A——Java函數是按值傳遞參數的!
剖析一下日記:
* 第一段日記輸入,value1參數在newValue辦法外部被改成指向新對象,並輸入了新對象的hashCode和value值,但跳出newValue辦法域以後,在main辦法中的value1沒有產生任何變更,這相符按值傳遞的界說和特色;假如是按援用傳遞,value1在挪用newValue(Value value)辦法以後,應當是產生變更的。
* 第二段日記輸入,value2在modifyValue辦法外部停止了setValue操作,hashCode不變而value被修正,分開modifyValue辦法域以後,在main辦法中value2確切產生了變革。應用過C++的人輕易將這類景象懂得為:按援用傳遞函數參數!由於這跟C++中的按援用傳遞像極了!但這裡恰好是最輕易墮入誤區的處所!
兩段日記的分歧景象面前所隱蔽的是道理是:Java說話是按值傳遞參數,按援用傳遞對象的;Java中所操作的對象其實都是操尴尬刁難象的援用,object自己保留在“堆”中,而對象的“援用“保留在存放器或“棧”中。
偽代碼描寫一下newValue辦法和modifyValue辦法的分歧的地方:
newValue{ Value_ref2 = value_ref1; // 按值傳入援用value_ref1,獲得value_ref1的正本 value_obj2 = new Value(); // value_obj2被創立、初始化在“堆“中 value_ref2 -> value_obj2; // value_ref2 指向value_obj2 value_ref2 ->value_obj2.setValue(“xxx”); // value_obj2 的value被修正 printValueObj2(); // 此處打印的是obj2的值 } modifyValue{ Value_ref2 = value_ref1; // 按值傳入援用value_ref1,獲得value_ref1的正本 value_ref2 ->value_obj1.setValue(“xxx”); // value_obj1 的value被修正 printValueObj1(); // 此處打印的是obj1的值 }
夠清晰了吧!value1_ref1在作為參數傳入函數的時刻,起首被復制了一份正本value1_ref2供函數域應用,此時這兩個ref都是指向統一個value_obj; newObject函數中的代碼[ value = new Value(); ] 實際上是將value1_ref1指向了一個新的對象value_obj2;在這以後的set操作都是對新對象的操作;modifyValue函數是經由過程set辦法直接操作value_obj1,這是跟newValue函數的分歧的地方。
經由過程值傳遞參數
挪用一個辦法時刻須要供給參數,你必需依照參數列表指定的次序供給。
例如,上面的辦法持續n次打印一個新聞:
public static void nPrintln(String message, int n) { for (int i = 0; i < n; i++) System.out.println(message); }
示例
上面的例子演示按值傳遞的後果。
該法式創立一個辦法,該辦法用於交流兩個變量。
public class TestPassByValue { public static void main(String[] args) { int num1 = 1; int num2 = 2; System.out.println("Before swap method, num1 is " + num1 + " and num2 is " + num2); // 挪用swap辦法 swap(num1, num2); System.out.println("After swap method, num1 is " + num1 + " and num2 is " + num2); } /** 交流兩個變量的辦法 */ public static void swap(int n1, int n2) { System.out.println("\tInside the swap method"); System.out.println("\t\tBefore swapping n1 is " + n1 + " n2 is " + n2); // 交流 n1 與 n2的值 int temp = n1; n1 = n2; n2 = temp; System.out.println("\t\tAfter swapping n1 is " + n1 + " n2 is " + n2); } }
以上實例編譯運轉成果以下:
Before swap method, num1 is 1 and num2 is 2 Inside the swap method Before swapping n1 is 1 n2 is 2 After swapping n1 is 2 n2 is 1 After swap method, num1 is 1 and num2 is 2
傳遞兩個參數挪用swap辦法。風趣的是,辦法被挪用後,實參的值並沒有轉變。