問題引入:在一個快速排序的函數 private void quickSort(List intList, int left, int right) 中,傳進去的參數intList是對象傳遞還是引用傳遞呢?
先抛出結論:
- 将對象(對象的引用)作為參數傳遞時傳遞的是引用(相當于指針)。也就是說函數内對參數所做的修改會影響原來的對象。
- 當将基本類型或基本類型的包裝集作為參數傳遞時,傳遞的是值。也就是說函數内對參數所做的修改不會影響原來的變量。
- 數組(數組引用))作為參數傳遞時傳遞的是引用(相當于指針)。也就是說函數内對參數所做的修改會影響原來的數組。
- String類型(引用)作為參數傳遞時傳遞的是引用,隻是對String做出任何修改時有一個新的String對象會産生,原來的String對象的值不會做任何修改。(但是可以将新的對象的 引用賦給原來的引用,這樣給人的表面現象就是原來的對象變了,其實沒有變,隻是原來指向它的引用指向了新的對象)。
舉例一:
public class Mainjava {
String str=new String("good");
char[] ch={'a','b','c'};
Integer i = ;
int x = ;
Test t1 = new Test();
Test t2 = new Test();
public static void main(String args[]){
Mainjava ex=new Mainjava();
ex.change(ex.str,ex.ch, ex.x, ex.i, ex.t1, ex.t2);
System.out.print(ex.str + " and ");
System.out.print(String.valueOf(ex.ch) + " and ");
System.out.print(ex.x + "," + ex.i + "," + ex.t1.getA() + "," + ex.t2.getA());
}
public void change(String str, char ch[], int x, Integer i, Test t1, Test t2){
str="test ok";
ch[]='g';
x = ;
i = ;
Test newT = new Test();
newT.setA();
t1 = newT;
t2.setA();
}
}
//Test類
public class Test {
private int a = ;
public void setA(int a){
this.a = a;
}
public int getA(){
return a;
}
}
輸出結果是多少呢?
good and gbc and 0,0,0,33
為什麼不是”test ok and gbc and 2,5,99,33”呢?
因為str是引用資料類型String,而字元數組是基本資料類型,二者存放在記憶體中的機制是不一樣的!
public void change(String str, char ch[], int x){
str = "test ok";
ch[] = 'g';
x = ;
}
change()方法傳入str,雖然把”test ok”強行賦給str,但是這裡的str存放在新的棧記憶體中,和原來的str存放的位址不一樣,是以你System.out.print(ex.str+”and”);這裡的輸出還是調用原來記憶體中的str;
字元數組不一樣,你聲明一個字元數組之後,那個數組的位置就定死了,你調用change()之後,把原來的字元數組的第1個元素改為了g.這就是引用資料類型和基本資料類型的差別。
舉例二:
import java.util.ArrayList;
import java.util.List;
public class Mainjava {
public static void main(String args[]){
List<Integer> integerList = new ArrayList<Integer>();
integerList.add();
integerList.add();
integerList.add();
integerList.add();
integerList.add();
integerList.add();
integerList.add();
integerList.add();
integerList.add();
integerList.add();
print(integerList);
quickSort(integerList, , integerList.size()-);
print(integerList); /*對比排序前後的integerList中的值,如果發生改變,說明是引用傳遞,即傳遞的是對象位址值*/
}
private static void quickSort(List<Integer> intList, int left, int right){
if(left >= right) {
return;
}
int i = left;
int j = right;
int key = intList.get(i);
System.out.println("key:"+"intList.get("+i+")="+key);
while(i < j){
while(i < j && intList.get(j) >= key){
j--;
}
intList.set(i, intList.get(j));
while(i < j && intList.get(i) <= key){
i++;
}
intList.set(j, intList.get(i));
}
intList.set(i, key);
quickSort(intList, left, i - );
quickSort(intList, i + , right);
}
private static void print(List<Integer> intList){
for (int i = ; i < intList.size(); i++) {
System.out.print(intList.get(i)+", ");
}
System.out.println("");
}
}
運作輸出結果如下:
7, 1, 3, 8, 9, 2, 5, 4, 10, 6,
key:intList.get(0)=7
key:intList.get(0)=6
key:intList.get(0)=2
key:intList.get(2)=3
key:intList.get(3)=4
key:intList.get(7)=9
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
結論:
實驗證明,Java中函數傳遞對象時,傳遞的是該對象的位址值,即引用傳遞。
函數傳遞基本類型資料時,傳遞的是值,也就是說函數傳回之後不會改變這個值。