问题引入:在一个快速排序的函数 private void quickSort(List
intList, int left, int right) 中,传进去的参数intList是对象传递还是引用传递呢?
先抛出结论:
将对象(对象的引用)作为参数传递时传递的是引用(相当于指针)。也就是说函数内对参数所做的修改会影响原来的对象。
当将基本类型或基本类型的包装集作为参数传递时,传递的是值。也就是说函数内对参数所做的修改不会影响原来的变量。
数组(数组引用))作为参数传递时传递的是引用(相当于指针)。也就是说函数内对参数所做的修改会影响原来的数组。
String类型(引用)作为参数传递时传递的是引用,只是对String做出任何修改时有一个新的String对象会产生,原来的String对象的值不会做任何修改。(但是可以将新的对象的 引用赋给原来的引用,这样给人的表面现象就是原来的对象变了,其实没有变,只是原来指向它的引用指向了新的对象)。
举例一:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42public class Mainjava {
String str=new String("good");
char[] ch={'a','b','c'};
Integer i = 0;
int x = 0;
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[0]='g';
x = 2;
i = 5;
Test newT = new Test();
newT.setA(99);
t1 = newT;
t2.setA(33);
}
}
//Test类
public class Test {
private int a = 0;
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,而字符数组是基本数据类型,二者存放在内存中的机制是不一样的!1
2
3
4
5public void change(String str, char ch[], int x){
str = "test ok";
ch[0] = 'g';
x = 2;
}
change()方法传入str,虽然把”test ok”强行赋给str,但是这里的str存放在新的栈内存中,和原来的str存放的地址不一样,所以你System.out.print(ex.str+”and”);这里的输出还是调用原来内存中的str;
字符数组不一样,你声明一个字符数组之后,那个数组的位置就定死了,你调用change()之后,把原来的字符数组的第1个元素改为了g.这就是引用数据类型和基本数据类型的区别。
举例二:
1 | import java.util.ArrayList; |
运行输出结果如下:
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中函数传递对象时,传递的是该对象的地址值,即引用传递。
函数传递基本类型数据时,传递的是值,也就是说函数返回之后不会改变这个值。