解惑:Java的方法参数总是按值传递

程序设计语言中往往分成按值调用和按引用调用。按值调用(call by value)表示方法接收的是调用者提供的值。而按引用调用(call by reference)表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。

​ 在Java程序设计语言中,方法参数总是按值调用。方法得到的是参数值的一个拷贝。特别需要注意的是,方法不能修改传递给它的任何参数变量的内容(这句话下文会通过三个例子来进行分析)

首先需要知道的是,Java的方法参数共有两种类型:

  1. 基本数据类型
  2. 对象引用

例子代码1:

public class ClassA {
    public static  void testCallByValue(int x){
        x++;
        System.out.println("testCallByValue: "+x);
    }

    public static void main(String[] arg){
        int y=1;
        testCallByValue(y);
        System.out.println("main: "+y);
    }
}

输出:

testCallByValue: 2
main: 1

可以看到,y被传入testCallByValue(int x)方法,参数x的值变为2,y本身的值依然为1,没有变化。

执行的具体过程如下:

  1. x被初始化为y值的拷贝(也就是1)
  2. x++,x的值变为2,y依然为1
  3. 方法结束,参数x不再使用

例子代码2:

public class ClassA {
    public static  void testCallByReference(List arrayListX){
        arrayListX.add(10000);
        arrayListX.add(10010);
        arrayListX.forEach(array->System.out.println("testCallByReference: "+array));
    }

    public static void main(String[] arg){
        List<Integer> arrayListY = new ArrayList<>();
        arrayListY.add(10086);
        testCallByReference(arrayListY);
        arrayListY.forEach(array->System.out.println("main: "+array));
    }
}

输出:

testCallByReference: 10086
testCallByReference: 10000
testCallByReference: 10010
main: 10086
main: 10000
main: 10010

可以看到arrayListY被传入testCallByReference(List arrayListX)方法后,自身的值也发生了改变。

执行的具体过程如下:

扫描二维码关注公众号,回复: 4470710 查看本文章
  1. arrayListX被初始化为arrayListY值的拷贝,这里是一个对象的引用(即arrayListX和arrayListY引用的同一个对象)
  2. testCallByReference(List arrayListX)方法应用于这个对象的引用,add成功
  3. 方法结束,参数arrayListX不再使用,arrayListY仍然引用着这个对象

例子代码3:

public class ClassA {
    public static  void testCallByReference(String strX){
        strX = "strX";
        System.out.println("testCallByReference: "+strX);
    }

    public static void main(String[] arg){
        String strY = "strY";
        testCallByReference(strY);
        System.out.println("main: "+strY);
    }
}

输出:

testCallByReference: strX
main: strY

可以看到strY被传入testCallByReference(String strX)方法后,自身的值没有改变。

执行的具体过程如下:

  1. strX被初始化为strY值的拷贝,这里是一个对象的引用(即strX和strY引用的同一个对象)
  2. testCallByReference(String strX)方法使strX引用了一个新的字符串对象,strY不会改变自身的引用
  3. 方法结束,参数strX不再使用,strY依然引用着"strY"这个对象

上面三个例子各做一个结论说明,分别是:

  1. 一个方法不能修改一个基本数据类型参数的值
  2. 一个方法可以改变一个对象参数的状态
  3. 一个方法不能让对象参数引用一个新的对象

猜你喜欢

转载自blog.csdn.net/wantaceveryday/article/details/84964437
今日推荐