title: java中的参数传递
date: 2019-03-14 21:52:03
categories: 代码
tags: java

Java中的参数传递

首先声明一点:Java中没有引用传递,只有值传递。

基本数据的按值传递

java的数据类型分为两大类,基本类型和引用类型。基本类型包括数值类型、字符类型、以及逻辑类型。
{% asset_img 数据类型.png 数据类型 %}
数据类型.png

基本类型的按值传递

  1. public class Swap {
  2. public static void main(String[] args) {
  3. int x = 10;
  4. int y = 20;
  5. swap(x, y);
  6. System.out.println("x(2) = " + x);
  7. System.out.println("y(2) = " + y);
  8. }
  9. public static void swap(int x, int y) {
  10. int temp = x;
  11. x = y;
  12. y = temp;
  13. System.out.println("x(1) = " + x);
  14. System.out.println("y(1) = " + y);
  15. }
  16. }
  17. /*输出
  18. x(1) = 20
  19. y(1) = 10
  20. x(2) = 10
  21. y(2) = 20
  22. */

上面程序main函数调用swap函数来交换 x,y的值,然而调用函数之后发现main中x,y的值并未交换。
{% asset_img 函数帧.png 函数帧 %}
函数帧.png

由上图可知,main函数中的x,y和swap函数中的x,y分别存放在不同的区域,在main中调用swap函数的时候,会将main中的x,y的值赋给swap中的x,y。当swap函数中对x,y交换时只是对swap帧中的x,y做交换,并不会改变main中的x,y。所以当函数返回时main中的x,y并不会改变。

{% asset_img swap函数帧.png swap函数帧 %}
swap函数帧.png
对于基本数据类型 short int long float double char byte boolean这八种按值传递调用函数并不会改变在原函数中的值。

引用数据类型的按值传递

引用数据类型分为3种:1接口,2类,3数组
代码示例

  1. public static void main(String[] args) {
  2. int []a={10,20};
  3. System.out.println("a[0] :"a[0]+"a[1] : "+a[1]);//a[0]=10,a[1]=20;
  4. swap(a, 0, 1);
  5. System.out.println("a[0] :"a[0]+"a[1] : "+a[1]);//a[0]=20,a[1]=10;
  6. }
  7. public static void swap(int []a,int i,int j){
  8. int temp=a[i];
  9. a[i]=a[j];
  10. a[j]=temp;
  11. System.out.println("a[0] :"a[0]+"a[1] : "+a[1]);//a[0]=20,a[1]=10;
  12. }
  13. //输出
  14. /*a[0]=10 a[1]=20
  15. a[0]=20 a[1]=10
  16. a[0]=20 a[1]=10
  17. */

运行程序后发现,swap函数对a[0] ,a[1]的操作竟然影响到了main函数中的a[0] ,a[1]的值,真是不可思议。为什么会产生如此之结果。原来引用类型的按值传递,传递的是对象的地址。还是用图来解释一下。

{% asset_img 引用数据类型函数帧.png 引用数据类型函数帧 %}
引用数据类型函数帧.png
由图可以看出在swap中仅仅是得到了数组的地址,并没有对数组的元素进行复制,在swap中对数组的操作是直接对main函数中数组的操作,因此swap函数返回后main函数中的a[0] ,a[1]的值发生交换。

数组、类、接口按值传递的时候都是传递对象的地址。再来看一个比较复杂的实例。

示例代码

  1. public class Main{
  2. public static void main(String[] args){
  3. Foo f = new Foo("f");
  4. changeReference(f); // It won't change the reference!
  5. modifyReference(f); // It will modify the object that the reference variable "f" refers to!
  6. }
  7. public static void changeReference(Foo a){
  8. Foo b = new Foo("b");
  9. a = b;
  10. }
  11. public static void modifyReference(Foo c){
  12. c.setAttribute("c");
  13. }
  14. }

1.png

2.png

3.png

4.png

5.png
5.1.png

6.png
以上说明 “在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。

转自:原博客地址