Java中的形参和实参的区别以及传值调用和传引用调用

本文详细解释了Java中的形参与实参概念,以及传值调用和传引用调用的原理。通过案例分析,展示了基础数据类型传值调用不会改变实参值,而对象引用类型传引用调用会改变实参对象的内容。总结指出Java的基本数据类型采用传值调用,对象引用类型采用传引用调用,强调了形参与实参之间的区别和交互方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址:http://blog.youkuaiyun.com/miniminiyu/article/details/52061401

 名词解析:

1.形参:用来接收调用该方法时传递的参数。只有在被调用的时候才分配内存空间,一旦调用结束,就释放内存空间。因此仅仅在方法内有效。

2.实参:传递给被调用方法的值,预先创建并赋予确定值。

3.传值调用:传值调用中传递的参数为基本数据类型,参数视为形参。

4.传引用调用:传引用调用中,如果传递的参数是引用数据类型,参数视为实参。在调用的过程中,将实参的地址传递给了形参,形参上的改变都发生在实参上。

      

 案例分析:

1.基础数据类型(传值调用)

传值,方法不会改变实参的值。


2.引用数据类型(引用调用)
传引用,方法体内改变形参引用,不会改变实参的引用,但有可能改变实参对象的属性值。

举两个例子:

  (1)方法体内改变形参引用,但不会改变实参引用 ,实参值不变。

  1. public class TestFun2 {  
  2. public static void testStr(String str){  
  3. str="hello";//型参指向字符串 “hello”  
  4. }  
  5. public static void main(String[] args) {  
  6. String s="1" ;  
  7. TestFun2.testStr(s);  
  8. System.out.println("s="+s); //实参s引用没变,值也不变  
  9. }  
执行结果打印:s=1
(2)方法体内,通过引用改变了实际参数对象的内容,注意是“内容”,引用还是不变的。
  1. public class TestFun4 {  
  2. public static void testStringBuffer(StringBuffer sb){  
  3. sb.append("java");//改变了实参的内容  
  4. }  
  5. public static void main(String[] args) {  
  6. StringBuffer sb= new StringBuffer("my ");  
  7. TestFun4.testStringBuffer(sb);  
  8. System.out.println("sb="+sb.toString());//内容变化了  
  9. }  
  10. }  

执行结果,打印:sb=my Java 。

  所以比较参数是String和StringBuffer 的两个例子就会理解什么是“改变实参对象内容”了。


  总结:

1.java的基本数据类型是传值调用,对象引用类型是传引用。

2.当传值调用时,改变的是形参的值,并没有改变实参的值,实参的值可以传递给形参,但是,这个传递是单向的,形参不能传递回实参。

3.当引用调用时,如果参数是对象,无论对对象做了何种操作,都不会改变实参对象的引用,但是如果改变了对象的内容,就会改变实参对象的内容。


<think>好的,用户问的是参数值调用方式中,形参实参是否是相同的存储空间。我需要先回忆一下C语言中参数递的基本概念,特别是值调用引用调用区别。用户可能对形参实参的关系有误解,或者想确认自己的理解是否正确。 首先,值调用(call by value)是指将实参复制给形参,这样形参实参其实是不同的内存空间。修改形参不会影响实参。这一点需要明确说明。而如果是引用或指针,虽然看起来像,但递的是地址,所以可以修改原变量,但这不属于值调用。 用户可能混淆了引用区别,或者想了解为什么有时候函数内修改参数不影响外面的变量。我需要用简单易懂的语言解释两者的区别,并强调存储空间的不同。同时,可能用户在实际编程中遇到了相关问题,比如函数内的修改没有生效,想了解原因。 接下来,我需要组织回答的结构。首先明确回答:不是,形参实参是不同的存储空间。然后解释值调用的过程,实参被复制到形参,两者独立。可以举一个例子,比如在函数中修改形参实参不变。同时对比引用或指针的情况,说明不同点。 还要注意用户可能的背景,可能刚开始学习编程,对内存模型不太熟悉,所以需要用比喻或者例子帮助理解。比如,把变量比作盒子,就是复制盒子的内容到另一个盒子,互不影响。而引用则是给原盒子一个别名,操作同一个盒子。 另外,要确保术语准确,避免混淆。例如,C语言中只有,但可以通过递指针来模拟引用。而C++中有真正的引用递。用户的问题没有限定语言,但通常以C为例,所以需要明确说明。 最后,总结关键点,确保用户理解形参实参的副本,存储空间独立,修改形参不影响实参。可能用户需要这样的理解来调试代码或设计函数参数递方式。</think>在参数值调用(**Call by Value**)方式中,**形参(形式参数)与实参(实际参数)并不是同一块存储空间**。以下是关键原理解释: --- ### **1. 值调用的核心机制** - **实参**:调用函数时递的具体(如变量、常量或表达式结果)。 - **形参**:函数定义中声明的局部变量,用于接收实参。 当函数被调用时,**实参会被复制一份**,赋形参。此时: - **形参实参的副本**,二者相同,但占用**独立的内存空间**。 - 在函数内部对形参的修改(如赋、运算等)**不会影响外部的实参**。 --- ### **2. 示例代码分析** ```c #include <stdio.h> void modify(int x) { // x 是形参,接收实参的副本 x = 10; // 修改的是形参 x,不影响外部的实参 } int main() { int a = 5; modify(a); // 实参 a 的(5)被复制给形参 x printf("%d", a); // 输出仍为 5,实参未被修改 return 0; } ``` - **内存分配**: - 实参 `a` 存储在 `main` 函数的栈帧中。 - 调用 `modify(a)` 时,形参 `x` 作为新变量被创建在 `modify` 函数的栈帧中,并存储 `a` 的副本(即 `5`)。 - 修改 `x` 时,仅影响 `modify` 栈帧中的副本,`main` 中的 `a` 保持不变。 --- ### **3. 与引用(Call by Reference)的对比** - **引用**(如 C++ 的 `&` 或指针递): - 形参实参的别名(或地址),**共享同一块内存空间**。 - 对形参的修改会直接影响实参。 - ****(C 语言默认行为): - 形参实参的独立副本,**不共享内存空间**。 - 对形参的修改仅在函数内部有效。 --- ### **4. 为什么需要值调用?** - **安全性**:避免函数意外修改外部数据。 - **隔离性**:函数内部逻辑与外部变量解耦,便于调试维护。 --- ### **5. 特殊情况:指针递(C 语言模拟“引用”)** C 语言中可通过递指针间接修改实参,但本质仍是****(递指针的副本): ```c void modify_pointer(int *p) { // p 是指针形参,接收地址的副本 *p = 10; // 通过地址修改原始数据 } int main() { int a = 5; modify_pointer(&a); // 递 a 的地址(递) printf("%d", a); // 输出 10 return 0; } ``` - **形参 `p`** 是 `&a` 的副本,但 `p` `&a` 指向同一块内存。 - 对 `*p` 的操作实际修改的是 `a` 的内存空间。 --- ### **总结** - **值调用中,形参实参是独立的内存空间**,修改形参不影响实参。 - 若需修改实参,需通过指针或引用(如 C++)递地址。 - 理解这一机制有助于避免函数设计中的逻辑错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值