博客

博客

值传递:对形参的修改不会影响到实参

引用传递:对形参的修改会影响实参

一、值传递

在主函数中

#include <iostream>
using namespace std;void main()
{int i=10;int j=i;j=20;cout<<"i="<<i<<endl;cout<<"j="<<j<<endl;system("pause");
}

输出结果为:

因为在int j=i 时,这是一个开辟一个新内存,然后将i中的值复制到j中的过程。所以,j中的值改变不会引起i中的值的改变。

二、地址传递

代码如下:

#include <iostream>
using namespace std;void main()
{int i=10;int *j=&i;*j=20;cout<<"i="<<i<<endl;cout<<"j="<<*j<<endl;system("pause");
}

输出结果为:

因为在 int *j=&i 时,这是一个开辟一个新内存,然后将i的地址的值传入到j中的过程。所以,*j =20就是访问j中地址(就是i的地址),将20赋值于其中,改变值(等于i=20)。

#include <iostream>
using namespace std;void test(int *j)
{*j=20;cout<<"j="<<*j<<endl;
}void main()
{int i=10;test(&i);cout<<"i="<<i<<endl;system("pause");
}

三、引用传递

代码如下:


```c
#include <iostream>
using namespace std;void main()
{int i=10;int &j=i;j=20;cout<<"i="<<i<<endl;cout<<"j="<<j<<endl;system("pause");
}

输出结果为:

因为在 int &j=i 时,这是将i 重命名为 j ,改变 j 的值等同改变 i 的值。

#include <iostream>
using namespace std;void test(int &j)
{j=20;cout<<"j="<<j<<endl;
}void main()
{int i=10;test(i);cout<<"i="<<i<<endl;system("pause");
}

总结
三种传递就是不一样的赋值结果,值传递,地址传递,引用传递分别为,j 复制 i 值,j 存入 i 的地址 ,i 重命名为 j 。

再次剖析值传递、引用传递

值传递、引用(地址)传递

public class MethodParamTest {public static void main(String[] args) {// 值传递int a = 10;change(a);System.out.println(a);// 10// 引用传递B b = new B();change(b);System.out.println(b.num);// 11}private static void change(int a) {++a;}public static void change(B b){++ b.num;}
}class B{public int num = 10;
}

值传递分析

引用传递

再再次剖析值传递、引用传递

值传递:对形参的修改不会影响到实参

引用传递:对形参的修改会影响实参

public class A {public static void example(int a){//形参a=20;System.out.println("形参:"+a);}public static void main(String[] args) {int a=10;//实参System.out.println("实参:"+a);example(a);//调用带有形参的方法System.out.println("实参"+a);}
}

输出结果

在基本类型的参数传递中我们可以发现:

基本类型当中,虽然形参修改后相关方法的值改变了,但是并没有影响到后序实参打印出来的值。

由此我们可以判断,在Java中基本类型使用的是值传递

引用类型

public class Person {public String name;public Person(String name){this.name=name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public static void main(String[] args) {Person p1=new Person("张三");System.out.println(p1.getName());p1.setName("李四");System.out.println(p1.getName());}
}

输出结果


在这里我们可以看到,在引用类型中将对象传递给方法中,在方法中改变形参的值,最后输出形参的值也会发生改变。

但是,这并不等于在引用类型中使用的是引用传递!

我们接着看

public class Person {public String name;public Person(String name){this.name=name;}public String getName() {return name;}public void setName(String name) {this.name = name;}public static void change(){Person p1=new Person("李四");System.out.println(p1.getName());}public static void main(String[] args) {Person p1=new Person("张三");System.out.println(p1.getName());change();System.out.println(p1.getName());}

输出结果

这时需要了解JVM基本知识

在JVM中,栈存储对象,而堆存储基本数据类型和局部变量

基本类型的参数传递过程中

我们可以发现,在操作带有形参的方法时,实际上相当于实参复制一个副本传递给形参,这样在修改形参方法之后,是不会影响到实参的。

而引用类型中

我们可以看到,当形参方法适用对象时,实际上是实参复制的一个副本,这个副本和主体一样,都可以操作堆中的内容。

因此,当调用形参方法中对堆中内容进行修改时,main方法中所指向的值也会改变。

实际上修改的是堆中的内容而并非修改了实参


而我们对自定义方法中,重新对对象开堆,那么实际上副本就引用了另一个堆的内容。

也就变成了两个对象引用两个堆,对其中一个进行修改自然不会影响另一个

结论:

Java当中只有值传递,没有引用传递 在基本类型进行参数传递的过程中,是将值复制一份传递给形参 如果是引用类型,就将引用复制一份传递给形参
无论如何,都无法通过形参改变实参

哈哈最后一次补充

public class Test {public static void mian(String[] args){int i = 1;String str = "hello";Interger num = 2;int[] arr = {1,2,3,4,5};MyData my = new MyData();chang(i,str,num,arr,my);System.out.println("i = "+ i);System.out.println("str = "+ str);System.out.println("num = "+ num);System.out.println("arr = "+ arr.toString(arr));System.out.println("my.a = "+ my.a);}public static void change(int j,String s,Integer n,int[] a,MyData m){j += 1;s += "world";n += 1;a[0] += 1;m.a += 1;}class MyData{int a = 10;}
}

输出结果

i——基本数据类型——传递数据值——不变; str——引用数据类型(String)——传递地址值——不变;
num——引用数据类型(包装类)——传递地址值——不变; arr——引用数据类型(数组)——传递地址值——变;
my——引用数据类型(对象)——传递地址值——变;

方法的参数传递机制:

形参是基本数据类型 传递数据值

实参是引用数据类型 传递地址值 特殊的类型:String、包装类等对象不可变性

总结:

  • 方法中的参数是形参,调用处传过来的参数是实参。
  • java的基本数据类型是传值调用,对象引用类型是传引用。
  • 当传值调用时,改变的是形参的值,并没有改变实参的值,实参的值可以传递给形参,但是,这个传递是单向的,形参不能传递回实参。
  • 当引用调用时,如果参数是对象,无论对对象做了何种操作,都不会改变实参对象的引用,但是如果改变了对象的内容,就会改变实参对象的内容。

java形参和实参的三种传递方式(值传递,地址传递,引用传递)相关推荐

  1. c语言 函数参数传递 值传递,c语言中函数参数的三种传递方式——值传递、指针传递、引用传递...

    函数参数有三种传递方式值传递.指针传递.引用传递. 1.值传递 将已经初始化的变量值(或常量)传递到函数中. 例如: int func(int value) { int ret = value++; ...

  2. C++函数的三种传递方式

    C++函数的三种传递方式为:值传递.指针传递和引用传递 值传递: void fun(int x){x += 5; //修改的只是y在栈中copy x,x只是y的一个副本,在内存中重新开辟的一块临时空间 ...

  3. 函数参数三种传递方式的区别

    函数参数三种传递方式的区别 问题提出: 1.当一个类的对象作为实参数传递时,使用值传递和引用传递有什么区别? 比如: DateType ExampleFun(CString &strFileN ...

  4. 转list_你知道Java数组转List的三种方式及对比吗?

    前言: 本文介绍Java中数组转为List三种情况的优劣对比,以及应用场景的对比,以及程序员常犯的类型转换错误原因解析. 一.最常见方式(未必最佳) 通过 Arrays.asList(strArray ...

  5. Java 数组转 List 的三种方式及对比

    来源 | blog.csdn.net/x541211190/article/details/79597236 本文介绍Java中数组转为List三种情况的优劣对比,以及应用场景的对比,以及程序员常犯的 ...

  6. Java 形参和实参

    /*-- 例子 --*/public class Test {public static void main(String[] args) {Integer a = 1;Integer b = 2;S ...

  7. Java数组转List的三种方式及对比

    前言: 本文介绍Java中数组转为List三种情况的优劣对比,以及应用场景的对比,以及程序员常犯的类型转换错误原因解析. 一.最常见方式(未必最佳) 通过 Arrays.asList(strArray ...

  8. 【零基础学Java】—this关键字的三种用法+Java继承的三个特点(二十一)

    [零基础学Java]-this关键字的三种用法+Java继承的三个特点(二十一) 一.this关键字的三种用法 在本类的成员方法中,访问本类的成员变量 在本类的成员方法中,访问本类的另一个成员方法 在 ...

  9. Java中List集合的三种遍历方式(全网最详)

    Map集合:链接: Map集合的五种遍历方式及Treemap方法 Set集合:链接: Java中遍历Set集合的三种方法 TreeSet集合:链接: Java深入了解TreeSet,和迭代器遍历方法 ...

最新文章

  1. python【蓝桥杯vip练习题库】ALGO-148 5-1最小公倍数(GCD)
  2. python怎么把程序封装成函数_PYTHON中如何把固定格式代码,封装成一个函数?
  3. 《看聊天记录都学不会C语言?太菜了吧》(5)打了一把游戏我学会了一个编程知识?
  4. JMeter - 如何创建可重用和模块化测试脚本
  5. 还争什么流量场景,罗振宇已经用时间挣钱了!
  6. java OOP及相关基础知识汇总(转)
  7. oracle 表 excel,《如何将oracle数据库表字段导成excel表格》
  8. 多目标优化问题和遗传算法学习
  9. 7步轻松设置授权管理器License Manager
  10. 一文带你入门 HTTP 协议
  11. vue-router 定义三级路由,路由跳转了,页面没出来
  12. c++多线程学习11 packaged_task与async
  13. 服务器固态硬盘raid没了,HP服务器磁盘阵列坏了怎么办,数据如何恢复?
  14. Linux安装mysql数据库
  15. Introduction to Graph Neural Network(图神经网络概论)翻译:Chapter2:Basic of Math and Graph
  16. ffmpeg 各版本下载以及在线安装
  17. mel编程相较于c语言怎么样,MEL语言
  18. 手机QQ浏览器如何支持html5,手机QQ浏览器五大策略打造HTML5平台
  19. 【支付架构】支付运营平台设计
  20. JavaScript 贪吃蛇游戏的实现

热门文章

  1. js中正则表达式的应用
  2. 向量逆时针旋转ang度
  3. 量化实战之银行零售资产分池
  4. python中wxpy的应用
  5. 自媒体如何快速涨粉?除了互粉还有这3个方法,能轻松上手
  6. Spring及Springboot IOC与AOP思考
  7. 正则中$1、$2的应用--日期格式化
  8. 【转】第5章 数据的描述性分析
  9. java继承1—上溯造型
  10. kali下的免杀之veil安装步骤