Java方法的参数传递方式只有一种:值传递,即将实参的副本传递给方法,参数本身不发生任何变化。先看看基本类型参数的传递示例:

Java数据传输类型 java传递参数的两种方式_System

public class TestPassPrimitiveArgs {
    public static void swap(int a, int b) {
        System.out.println("交换前,a = " + a + ", b = " + b);//a = 3,b = 5
        int temp = a;
        a = b;
        b = temp;
        System.out.println("交换后,a = " + a + ", b = " + b);//a = 5,b = 3
    }
    public static void main(String[] args) {
        int a = 3;
        int b = 5;    
        swap(a, b);
        System.out.println("交换结束后,a = " + a + ", b = " + b);//a = 3,b = 5
    }
}

Java数据传输类型 java传递参数的两种方式_System

从运行结果来看,在swap()中交换之前是3和5,交换后变成5和3,而实参在main()中始终变成不变,因此在main()传递给swap()的实参只是a和b的副本,而不是a和b本身。我们以内存分布来说明执行状况,当在main()中传参给swap()时,实际上就是在main()方法栈区向swap()方法栈区传递一份a和b的副本,如下图:

Java数据传输类型 java传递参数的两种方式_java基础_03

当执行swap()时,swap()方法栈区将a和b副本进行交换,交换完成后进入main()方法栈区,此时仅仅a和b的副本发生改变,其本身没有发生任何变化。接下来我们来看看引用类型的交换,前面我们说了只能通过值传递的方式来传参,可能对有些朋友来说稍显疑惑。

Java数据传输类型 java传递参数的两种方式_System

class DataSwap {
    public int a;
    public int b;
}
public class TestPassReferenceArgs {
    public static void swap(DataSwap ds) {
        System.out.println("交换前,ds.a = " + ds.a + ", ds.b = " + ds.b);//ds.a = 3, ds.b = 5
        int temp = ds.a;
        ds.a = ds.b;
        ds.b = temp;
        System.out.println("交换后,ds.a = " + ds.a + ", ds.b = " + ds.b);//ds.a = 5, ds.b = 3
    }
    public static void main(String[] args) {
        DataSwap ds = new DataSwap();
        ds.a = 3;
        ds.b = 5;
        swap(ds);
        System.out.println("交换结束后,ds.a = " + ds.a + ", ds.b = " + ds.b);//ds.a = 5, ds.b = 3
    }
}

Java数据传输类型 java传递参数的两种方式_System

从运行结果来看,确实不仅在swap中交换成功,在main中仍然是交换之后的结果。让人一下觉得:从main中传递给swap似乎不是ds对象的副本了,而是ds本身,这与我们前面谈到的Java方法传参只能按值传递相违背了,下面我详细说明一下。我们都知道,此时传递的是引用类型DataSwap,而引用类型的内存方式已经谈过了,在main()方法栈区中实际存放的是ds对象的地址,而实际的数据(a,b)是存放在堆内存中。现在将ds对象引用由main传递给swap,实际上是ds对象的地址复制一份到swap方法栈区中,此时main和swap中都已拥有ds对象的地址,且都指向在堆内存中实际存放的数据。也就是说引用类型参数数据传递方式是不折不扣的值传递方式,只不过传递的仅仅是引用变量,而不是引用变量所指向的引用类型数据。当然这里对main或swap中任何一个ds对象数据的更改都会影响到另一方,同时我们还可以验证main和swap中的ds是两个不同的引用变量,试着在swap种方法最后添加: ds=null.也就是切断swap中对ds的引用,查看一下main中ds对象的a和b是否受到影响(结果是不会)。

Java数据传输类型 java传递参数的两种方式_数据_06

Java数据传输类型 java传递参数的两种方式_java基础_07