admin 管理员组

文章数量: 1086019

什么值传递和引用传递

经常听别人说值传递和引用传递,其实很多人初学者都搞不懂这两个的区别,今天就来讲下什么是值传递和引用传递

值传递和引用传递概述

那怎么是值传递呢,顾名思义,就是我给你个值,然后你可以拿到这个值,这种值传递是基于基本类型的传递,如下所示

int a=1;//定义变量a赋值为1
int b;

此时的内存结构应该是这样的

经过赋值后

b=a;

内存结构就会变成这样

那么什么是引用传递呢,其实引用传递都是针对对象而言,总所周知中的对象存的都是内存地址值,例如

String s1=new String("aaa");
String s2;

那么他的内存结构应该是这样的
其中,xxxx为s1的地址值,当new对象的时候,会在内存中开辟出一个地址空间,然后s1的地址值则会指向内存中的String实例,

那么将s2赋值后会发生什么变化呢

s2=s1;

如下图所示,就会吧s1的xxxx地址值给了s2,那么现在s2中的xxxx地址值也是指向了S1所new的那个Spring实例,也就是说,引用传递传的是地址值,但是还是指向了相同的实例
但是我看过很多博客也说过,其实地址值也是值,所以引用传递的本质也是值传递

ps:个人理解:用通俗的话讲就是,值传递,我有一个苹果,我值传递后,就会变成你有一个苹果,我有一个苹果。引用传递,我有一个苹果,我引用传递给你后,我们大家共用一个苹果(讲的不好忽略,个人理解)

看了上面两个例子相信大家对值传递和引用传递有了大概的了解,那下面讲几个例子让大家更容易理解

例子讲解

1.值传递示例

	public static int i=1;public static void main(String[] args) {func(i);System.out.println(“i=”+i);}public static void func(int i) {i=0;}

控制台输出i=1

这里应该没什么问题,这里不多做讲解,i的值传入func中方法中的参数i,原来的i值并没有改变,所以i=1
2.引用传递示例1

	public static String str=new String("good");public static void main(String[] args) {func(str);System.out.println("s1的值为:"+str);}public static void func(String str) {str=new String("bbb");}

控制台输出:str的值为:good

实参中未new对象的内存结构

实参中new了对象后(注:地址值是我随便写的,真实地址值不会这样,这样写只是方便理解)

方法中的实参str接收到成员变量str传入的地址值后,方法中的str就会指向"good"实例,而new了对象后地址就改变了,所以指向了"bbb"实例,但是mian方法中打印的str的值还是good,因为他的地址值还是指向good,而good的值也没有发生改变

这时大家肯定会疑问,那这样和值传递有什么区别,好像两个示例比起来没什么区别,那接下看下面的例子
3.引用示例3

	public static StringBuilder sb=new StringBuilder("good");public static void main(String[] args) {func(sb);System.out.println("sb的值为:"+sb);}public static void func(StringBuilder sb) {sb.append("bbb");}

控制台输出:sb的值为:goodbbb

看到这里,相信大家都发现问题了吧,问什么方法中的sb添加bbb后会影响到上面成员变量的sb的值呢,直接上图看

调用func方法未调用append时的内存结构

调用append方法后

如图上两幅图所示,在调用func方法的时候,实参中的sb拿到了传入的sb的地址值,这时候实参中的sb指向了"good"实例,然后调用append方法的时候并没有创建新的对象,还是指向"good"实例,所以改实例就会变成“goodbbb”,而在main方法中sb变量也是指向相同地址的实例,所以打印出来就会变成“goodbbb”

看到这里相信大家已经了解到什么是值传递和引用传递了,那我们再来个很有意思的例子巩固下

	public static void main(String[] args) {ArrayList<HashMap<String, Integer>> list=new ArrayList<>();HashMap<String, Integer> map=new HashMap<>();for (int i = 1; i <= 5; i++) {map.put("测试", i);list.add(map);}	System.out.println(list);}

控制台输出 :[{测试=5}, {测试=5}, {测试=5}, {测试=5}, {测试=5}]

public static void main(String[] args) {ArrayList<HashMap<String, Integer>> list=new ArrayList<>();for (int i = 1; i <= 5; i++) {HashMap<String, Integer> map=new HashMap<>();map.put("测试", i);list.add(map);}	System.out.println(list);}

控制台输出:[{测试=1}, {测试=2}, {测试=3}, {测试=4}, {测试=5}]

看到这,相信大家已经了解了什么是值传递和引用传递了吧。有不对的地方欢迎大家指出

本文标签: 什么值传递和引用传递