Java编程基础:浅析调用Java方法时的参数传递机制

在Java代码中调用方法时传递参数有两种方式:一种是传值,一种是传引用。如果是用Java的基本类型(int,boolean等)做参数认为是传值,如果是对象类型则认为是传引用。下面来剖析一下传对象引用这种场景。

看下面这道Java基础题

package com.elon.integertest;

public class StartupIntegerTest {
    public static void main(String[] args) {
        Integer i = new Integer(1);
        System.out.println("a: i=" + i);
        change(i);
        System.out.println("c: i=" + i);

        System.exit(0);
    }

    private static void change(Integer i) {
        int value = i + 2;
        i = new Integer(value);
        System.out.println("b: i=" + i);
    }
}

运行程序后输出如下信息:
这里写图片描述

从输出的结果可以看到在change()方法中修改了 i 变量的值,但这种修改并未带出方法外,退出change()方法后,i 的值还是1。参数 i 是integer的对象类型,按理传入的是对象引用,修改了数据能够带出来才对,这是怎么回事呢?我们需要分析一下在main函数中调用change()方法时具体传入的是什么,在change()方法中修改了什么。

调用方法时传递参数,本质上是做数据拷贝(参数压栈)。只不过传值是拷贝对象的内容,传引用是拷贝对象的地址。上面的方法调用过程中将 i 变量的地址传递到了change()方法中,传递的是一个32位的地址指针(64位操作系统,指针是64位);在change()方法中定义了一个参数变量 i 来存储这个地址(注意的是在change方法中的变量 i 与main方法中的变量 i 不是同一个变量,只是它们都指向了一个值为1的变量空间)。

既然两个 i 不是同一个变量,那么在change()方法中通过new新申请一片空间给 i 赋值,只是让change()方法内的 i 变量指向了一片新的空间。对main方法中的 i 变量不会有任何影响,也就不会改变它所指向地址空间中存储的具体值。

在C++代码中调试印证

在JAVA中看不到变量的地址,把上面的代码逻辑放到C++中调试一下就很清楚了。

  1. 可以看到一开始p指针指向的int型变量的地址是0x06bd5398:

这里写图片描述

  1. p变量本身的地址是0x0031efac, 即指向指针的指针是0x0031efac:

这里写图片描述

  1. 进入change()函数后,可以看到参数p的值是0x06bd5398。形式参数p与mian函数中的指针p指向的是同一个对象。

这里写图片描述

  1. 形参p本身的地址是0x007bf340,说明change()函数定义了一个新的指针变量p,与main中的p指针不同(只是刚好名字相同而已)。

这里写图片描述

经过上面的分析可知 在change()中重新分配一个int对象,使用p指针指向它。改变这个新分配变量的值,不会影响到main中分配的那个int变量的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值