今天小夥伴問我一段代碼:
public static ListNode create(int[] array) {
if (array == null || array.length == 0)
return null;
ListNode head = new ListNode(0);
ListNode node = head;
for (int i = 0; i < array.length; i++) {
ListNode temp = new ListNode(array[i]);
node.next = temp;
node = temp;
System.out.println(node.val);
}
return head.next;
}
爲什麼在方法內head指向的是鏈表的最後一個結點,但是在main方法中head指向的是第一個結點。
我進行了測試
public class Main {
public static class ListNode{
int val;
ListNode next; //下一個鏈表對象
ListNode(int x){val=x;} //賦給結點的值
}
public static ListNode create(int[] array) {
if (array == null || array.length == 0)
return null;
ListNode head = new ListNode(0); //預指針,其下一個結點指向真正的頭結點
ListNode node = head;
for (int i = 0; i < array.length; i++) {
ListNode temp = new ListNode(array[i]);
node.next = temp;
node = temp;
System.out.println(node.val);
}
return head.next;
}
public static void main(String[] args)
{
int[] array={1,2,3,4,5,6,7,8,9};
ListNode a=create(array);
System.out.println("---------"+a.val);
}
}
發現真的是a.val輸出爲1。
後來經過一波討論,查閱了很多資料得出一下結論。
這是因爲ListNode a=create(array);被初始化,將head.next的初值1賦值給了a。然後再執行create方法。但由於java的引用傳遞,雖然方法內head的最後的值變爲9,但是最後賦值給a的值依然爲其初始值1。
值傳遞:
在方法被調用時,實參通過形參把它的內容副本傳入方法內部,此時形參接收到的內容是實參值的一個拷貝,因此在方法內對形參的任何操作,都僅僅是對這個副本的操作,不影響原始值的內容。
引用傳遞:
引用也就是指向真實內容的地址值,在方法調用時,實參的地址通過方法調用被傳遞給相應的形參,在方法體內,形參和實參指向內存地址,對形參的操作會影響的真實值。
JVM內存模型中,方法是存在虛擬棧中的,一個線程獨享一個棧,而堆和方法區是所有線程共享的。JAVA的引用傳進函數時 , 會複製一個引用與實參指向同一對象的引用, 操作的不是同一個引用。如下圖所示:
總的來說就是隻有當變量本身的值發生改變,值纔會改變。