【Java】函数中的参数传递是“引用传递”还是“值传递”?

分手后的思念是犯贱 2022-08-09 16:58 311阅读 0赞

问题引入:在一个快速排序的函数 private void quickSort(List intList, int left, int right) 中,传进去的参数intList是对象传递还是引用传递呢?

先抛出结论:

  1. 将对象(对象的引用)作为参数传递时传递的是引用(相当于指针)。也就是说函数内对参数所做的修改会影响原来的对象。
  2. 当将基本类型或基本类型的包装集作为参数传递时,传递的是值。也就是说函数内对参数所做的修改不会影响原来的变量。
  3. 数组(数组引用))作为参数传递时传递的是引用(相当于指针)。也就是说函数内对参数所做的修改会影响原来的数组。
  4. String类型(引用)作为参数传递时传递的是引用,只是对String做出任何修改时有一个新的String对象会产生,原来的String对象的值不会做任何修改。(但是可以将新的对象的 引用赋给原来的引用,这样给人的表面现象就是原来的对象变了,其实没有变,只是原来指向它的引用指向了新的对象)。

举例一:

  1. public class Mainjava {
  2. String str=new String("good");
  3. char[] ch={
  4. 'a','b','c'};
  5. Integer i = 0;
  6. int x = 0;
  7. Test t1 = new Test();
  8. Test t2 = new Test();
  9. public static void main(String args[]){
  10. Mainjava ex=new Mainjava();
  11. ex.change(ex.str,ex.ch, ex.x, ex.i, ex.t1, ex.t2);
  12. System.out.print(ex.str + " and ");
  13. System.out.print(String.valueOf(ex.ch) + " and ");
  14. System.out.print(ex.x + "," + ex.i + "," + ex.t1.getA() + "," + ex.t2.getA());
  15. }
  16. public void change(String str, char ch[], int x, Integer i, Test t1, Test t2){
  17. str="test ok";
  18. ch[0]='g';
  19. x = 2;
  20. i = 5;
  21. Test newT = new Test();
  22. newT.setA(99);
  23. t1 = newT;
  24. t2.setA(33);
  25. }
  26. }
  27. //Test类
  28. public class Test {
  29. private int a = 0;
  30. public void setA(int a){
  31. this.a = a;
  32. }
  33. public int getA(){
  34. return a;
  35. }
  36. }

输出结果是多少呢?

good and gbc and 0,0,0,33

为什么不是”test ok and gbc and 2,5,99,33”呢?

因为str是引用数据类型String,而字符数组是基本数据类型,二者存放在内存中的机制是不一样的!

  1. public void change(String str, char ch[], int x){
  2. str = "test ok";
  3. ch[0] = 'g';
  4. x = 2;
  5. }

change()方法传入str,虽然把”test ok”强行赋给str,但是这里的str存放在新的栈内存中,和原来的str存放的地址不一样,所以你System.out.print(ex.str+”and”);这里的输出还是调用原来内存中的str;
字符数组不一样,你声明一个字符数组之后,那个数组的位置就定死了,你调用change()之后,把原来的字符数组的第1个元素改为了g.这就是引用数据类型和基本数据类型的区别。


举例二:

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. public class Mainjava {
  4. public static void main(String args[]){
  5. List<Integer> integerList = new ArrayList<Integer>();
  6. integerList.add(7);
  7. integerList.add(1);
  8. integerList.add(3);
  9. integerList.add(8);
  10. integerList.add(9);
  11. integerList.add(2);
  12. integerList.add(5);
  13. integerList.add(4);
  14. integerList.add(10);
  15. integerList.add(6);
  16. print(integerList);
  17. quickSort(integerList, 0, integerList.size()-1);
  18. print(integerList); /*对比排序前后的integerList中的值,如果发生改变,说明是引用传递,即传递的是对象地址值*/
  19. }
  20. private static void quickSort(List<Integer> intList, int left, int right){
  21. if(left >= right) {
  22. return;
  23. }
  24. int i = left;
  25. int j = right;
  26. int key = intList.get(i);
  27. System.out.println("key:"+"intList.get("+i+")="+key);
  28. while(i < j){
  29. while(i < j && intList.get(j) >= key){
  30. j--;
  31. }
  32. intList.set(i, intList.get(j));
  33. while(i < j && intList.get(i) <= key){
  34. i++;
  35. }
  36. intList.set(j, intList.get(i));
  37. }
  38. intList.set(i, key);
  39. quickSort(intList, left, i - 1);
  40. quickSort(intList, i + 1, right);
  41. }
  42. private static void print(List<Integer> intList){
  43. for (int i = 0; i < intList.size(); i++) {
  44. System.out.print(intList.get(i)+", ");
  45. }
  46. System.out.println("");
  47. }
  48. }

运行输出结果如下:

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中函数传递对象时,传递的是该对象的地址值,即引用传递。
函数传递基本类型数据时,传递的是,也就是说函数返回之后不会改变这个值。

发表评论

表情:
评论列表 (有 0 条评论,311人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java传递引用传递

    值传递和引用传递最大的区别是传递的过程中有没有复制出一个副本来,如果是传递副本,那就是值传递,否则就是引用传递。 Java对象的传递,是通过复制的方式把引用关系传递了,因为有

    相关 java传递引用传递

    在Java中一切皆对象,无论是int a;还是String a;,这两个变量a都是对象。 在传递的时候究竟是按什么方式传递的呢?其答案就是:即是按值传递也是按引用传递,但通