传递数组对象_Java中对值传递的思考,测试题15

  周末在做Java测试题的时候,有一个关于值传递的,今天拿出来大家看看,是不是能够理解。

public class CoolTestDemo {

    public static void main(String[] args){

        int[] myArray = {1,2,3,4,5};

        ChangeIt.doIt(myArray);

        for (int i = 0; i < myArray.length; i++) {

            System.out.println(myArray[i] + "");

        }

    }

}

class ChangeIt{

    public static void doIt(int[] nums){

        nums = null;

    }

}

这个程序我们运行之后,应该是什么结果呢?

我先来自己分析下:

首先定义了一个数组,然后调用外部类的方法 ChangeIt.doIt() 去调用参数

这里的参数,我理解是外部类方法中的入参。如果是这么理解的话,那么调用的应该是 nums = null 为什么运行后还是 1,2,3,4,5呢?

相当于在类 TestIt中运行外部类.方法(入参),但是还是调用的基础数据类型 myArray 没有调用 z = null

到底是不是这样呢?我们来具体看下:

调用方法的时候,有需要传参数的情况。在java中,参数的类型有基本类型和引用类型两种。把数组引用变量作为参数传递到一个方法中进行操作之后,再去访问原数组,原数组元素的值改变了。当Java将引用类型变量作为参数传递给方法时,到底是值传递还是引用传递。

我们说下结论:

如果将Java引用类型变量作为参数传递给方法,是将引用变量的值传递给形参,而引用变量的值实际上就是引用对象在堆内存中的地址。也就是说,这个时候实参和形参都指向了同一个对象,如果利用形参进行操作,操作的就是实参指向的对象,最后通过实参的那个引用访问,自然是被形参操作过的结果

我们来看个例子:

public class Main {

public static void main(String[] args) {

int num1 = 11;

int num2 = 22;

System.out.println("Before the call: num1 is " + num1 + " and num2 is " + num2);

swap(num1, num2);

System.out.println("After the call: num1 is " + num1 + " and num2 is " + num2);

}

public static void swap(int num1, int num2) {

System.out.println("num1 is " + num1 + " and num2 is " + num2 + " in method of swap.(before)");

int tmp = num1;

num1 = num2;

num2 = tmp;

System.out.println("num1 is " + num1 + " and num2 is " + num2 + " in method of swap.(after)");

}

}

运行下结果:

Before the call: num1 is 11 and num2 is 22

num1 is 11 and num2 is 22 in method of swap.(before)

num1 is 22 and num2 is 11 in method of swap.(after)

After the call: num1 is 11 and num2 is 22

通过运行结果,可以清楚地知道,通过这样的参数传递,交换的仅仅是形参的值,而main方法当中的两个数的值并没有发生变化。这就是值传递的结果

我们再看下引用类型参数:

public class ArrayTest {

public static void main(String[] args) {

int[] arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

System.out.print("Before calling the inversion: ");

for (int i : arr) {

System.out.printf("%3d", i);

}

System.out.println();

inversion(arr);

System.out.print(" After calling the inversion: ");

for (int i : arr) {

System.out.printf("%3d", i);

}

System.out.println();

setNull(arr);

System.out.println("@" + arr);

}

public static void inversion(int[] arr) {

int length = arr.length;

for (int i = 0; i <= length / 2; i++) {

int temp = arr[i];

arr[i] = arr[length - i - 1];

arr[length - i -1] = temp;

}

}

public static void setNull(int[] array) {

System.out.println("#" + array);

array = null;

System.out.println("$" + array);

}

}

看下运行结果:

Before calling the inversion:   0  1  2  3  4  5  6  7  8  9

   After calling the inversion:   9  8  7  6  4  5  3  2  1  0

#[I@1d251891

$null

@[I@1d251891 

程序中,在main方法中定义了一个数组,并且在类中定义了一个将数组元素倒置的方法inversion(),这个方法需要传入一个数组类型的引用。在main方法中调用这个方法,并将arr这个数组的引用作为参数传递给inversion方法,通过程序执行的结果,可以看到当inversion方法执行完毕,main方法中的arr数组的内容的确发生了倒置。

那么,这个时候是否就可以认为,引用类型的传递是引用传递而并非值传递呢?按照资料显示的,引用类型的参数传递传递的是引用变量的值,有什么方法可以证明一下呢?setNull()方法提供了这样的证明。

setNull方法的参数是数组的引用变量,程序中传入的是arr.进入方法,首先打印了array,然后将它置空再打印一次,然后在main方法中,打印arr的地址。程序运行的结果表示,array置空之前和arr指向的是同一区域,而后array=null却并没有影响到arr.

所以,可以肯定,当一个引用类型的变量被作为参数传递到方法中的时候,仅仅是将变量值复制后传递过去,而本身没有发生改变去指向其他。

2e903de382871b7b691d6e19b69c4c7c.png

当array=null的时候,array指向堆区的引用失效了。

以上的示例和分析都表明,Java中的确没有引用传递,当把一个引用类型的变量作为参数传递给方法的时候,也仅仅是将引用变量的值复制一份给了方法中的参数,自己始终指向原本的对象

好的,今天就先说到这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值