Java基础中按值传递和引用传递详解

下面是我在网上看到的一个帖子,解释的感觉挺全面,就转过来,以供以后学习参考:

       

1:按值传递是什么

指的是在方法调用时,传递的参数是按值的拷贝传递。示例如下:

[java] view plaincopy
  1. public class TempTest {  
  2. private void test1(int a){  
  3. //做点事情  
  4. }  
  5. public static void main(String[] args) {  
  6. TempTest t = new TempTest();  
  7. int a = 3;  
  8. t.test1(a);//这里传递的参数a就是按值传递  
  9. }  
  10. }  

按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了。

示例如下:

[java] view plaincopy
  1. public class TempTest {  
  2. private void test1(int a){  
  3. a = 5;  
  4. System.out.println("test1方法中的a="+a);  
  5. }  
  6. public static void main(String[] args) {  
  7. TempTest t = new TempTest();  
  8. int a = 3;  
  9. t.test1(a);//传递后,test1方法对变量值的改变不影响这里的a  
  10. System.out.println(”main方法中的a=”+a);  
  11. }  
  12. }  

运行结果是:

[java] view plaincopy
  1. test1方法中的a=5  
  2. main方法中的a=3  


2:按引用传递是什么

指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。

示例如下:

[java] view plaincopy
  1. public class TempTest {  
  2. private void test1(A a){  
  3. }  
  4. public static void main(String[] args) {  
  5. TempTest t = new TempTest();  
  6. A a = new A();  
  7. t.test1(a); //这里传递的参数a就是按引用传递  
  8. }  
  9. }  
  10. class A{  
  11. public int age = 0;  
  12. }  

3:按引用传递的重要特点

传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。

示例如下:


[java] view plaincopy
  1. public class TempTest {  
  2. private void test1(A a){  
  3. a.age = 20;  
  4. System.out.println("test1方法中的age="+a.age);  
  5. }  
  6. public static void main(String[] args) {  
  7. TempTest t = new TempTest();  
  8. A a = new A();  
  9. a.age = 10;  
  10. t.test1(a);  
  11. System.out.println(”main方法中的age=”+a.age);  
  12. }  
  13. }  
  14. class A{  
  15. public int age = 0;  
  16. }  

运行结果如下:

[java] view plaincopy
  1. test1方法中的age=20  
  2. main方法中的age=20  

4:理解按引用传递的过程——内存分配示意图

要想正确理解按引用传递的过程,就必须学会理解内存分配的过程,内存分配示意图可以辅助我们去理解这个过程。

用上面的例子来进行分析:

(1):运行开始,运行第8行,创建了一个A的实例,内存分配示意如下:



(2):运行第9行,是修改A实例里面的age的值,运行后内存分配示意如下:


(3):运行第10行,是把main方法中的变量a所引用的内存空间地址,按引用传递给test1方法中的a变量。请注意:这两个a变量是完全不同的,不要被名称相同所蒙蔽。

内存分配示意如下:


由于是按引用传递,也就是传递的是内存空间的地址,所以传递完成后形成的新的内存示意图如下:


也就是说:是两个变量都指向同一个空间。

(4):运行第3行,为test1方法中的变量a指向的A实例的age进行赋值,完成后形成的新的内存示意图如下:


此时A实例的age值的变化是由test1方法引起的

(5):运行第4行,根据此时的内存示意图,输出test1方法中的age=20

(6):运行第11行,根据此时的内存示意图,输出main方法中的age=20


5:对上述例子的改变

理解了上面的例子,可能有人会问,那么能不能让按照引用传递的值,相互不影响呢?就是test1方法里面的修改不影响到main方法里面呢?

方法是在test1方法里面新new一个实例就可以了。改变成下面的例子,其中第3行为新加的:

[java] view plaincopy
  1.  public class TempTest {  
  2.  private void test1(A a){  
  3.  a = new A();//新加的一行  
  4.  a.age = 20;  
  5.  System.out.println("test1方法中的age="+a.age);  
  6.  }  
  7.  public static void main(String[] args) {  
  8.  TempTest t = new TempTest();  
  9.  A a = new A();  
  10.  a.age = 10;  
  11.  t.test1(a);  
  12.  System.out.println(”main方法中的age=”+a.age);  
  13.  }  
  14. }  
  15. class A{  
  16.  public int age = 0;  
  17. }  

运行结果为:

[java] view plaincopy
  1. test1方法中的age=20  
  2. main方法中的age=10  

为什么这次的运行结果和前面的例子不一样呢,还是使用内存示意图来理解一下

6:再次理解按引用传递

(1):运行开始,运行第9行,创建了一个A的实例,内存分配示意如下:

(2):运行第10行,是修改A实例里面的age的值,运行后内存分配示意如下:

(3):运行第11行,是把main方法中的变量a所引用的内存空间地址,按引用传递给test1方法中的a变量。请注意:这两个a变量是完全不同的,不要被名称相同所蒙蔽。

内存分配示意如下:

由于是按引用传递,也就是传递的是内存空间的地址,所以传递完成后形成的新的内存示意图如下:


也就是说:是两个变量都指向同一个空间。

(4):运行第3行,为test1方法中的变量a重新生成了新的A实例的,完成后形成的新的内存示意图如下:

(5):运行第4行,为test1方法中的变量a指向的新的A实例的age进行赋值,完成后形成的新的内存示意图如下:

注意:这个时候test1方法中的变量a的age被改变,而main方法中的是没有改变的。

(6):运行第5行,根据此时的内存示意图,输出test1方法中的age=20

(7):运行第12行,根据此时的内存示意图,输出main方法中的age=10

7:说明

(1):“在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。

(2):在Java里面只有基本类型和按照下面这种定义方式的String是按值传递,其它的都是按引用传递。就是直接使用双引号定义字符串方式:String str = “Java私塾”;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457044.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Foreign】采蘑菇 [点分治]

采蘑菇 Time Limit: 20 Sec Memory Limit: 256 MBDescription Input Output Sample Input 51 2 3 2 31 21 32 42 5Sample Output 10912911HINT Main idea 询问从以每个点为起始点时,各条路径上的颜色种类的和。 Solution 我们看到题目,立马想到了O(n^2)…

c语言程序设计贪吃蛇需求分析,C语言编程新手入门基础进阶学习!贪吃蛇小游戏演示和说明...

C语言是面向过程的,而C++是面向对象的设计贪吃蛇游戏的主要目的是让大家夯实C语言基础,训练编程思维,培养解决问题的思路,领略多姿多彩的C语言。游戏开始后,会在中间位置出现一条只有三个节点的…

Strus2中关于ValueStack详解

什么是ValueStack 它是一个接口com.opensymphony.xwork2.util.ValueStack。我们使用它是将其做为一个容器,用于携带action数据到页面。在页面上通过ognl表达式获取数据。 valueStack主要是将action数据携带到页面上,通过ognl获取数据 1.ValueStack有一个…

c语言递归汉诺塔次数,汉诺塔问题(C语言经典递归问题(一))

把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。思路:图解&#xff1a…

理解浏览器是如何加载及渲染网页的

先上图,我们再慢慢解释,这图就是浏览器加载网页的一个过程 当我们在浏览器输入一个地址(比如:http://toadw.cn),那么点击回车后,浏览器是如何加载网页的呢? 加载过程 一开始浏览器是不知道你输入的http://t…

CentOS下的Mysql的安装和使用

1.使用安装命令 :yum -y install mysql mysql-server mysql-devel 安装完成却发现Myserver安装缺失,在网上找原因,原来是因为CentOS 7上把MySQL从默认软件列表中移除了,用MariaDB来代替,所以这导致我们必须要去官网上…

Android中创建自己的对话框

Activities提供了一种方便管理的创建、保存、回复的对话框机制,例如 onCreateDialog(int), onPrepareDialog(int, Dialog), showDialog(int), dismissDialog(int)等方法,如果使用这些方法的话,Activity将通过getOwnerActivity()方法返回该Act…

一件很好笑的事情

我是一个比较习惯努力学习的人, 我也会去学习各种可能与我有交集的知识, 就在这几天,我看到以前的一个android网络培训学校开办了C/C的培训,这是挺好的事, 但是看他们的文件,我就奇怪了。 这份文件&#xf…

关于Eclipes的Logcat无法打印消息的解决办法

转自:http://blog.csdn.net/harry211/article/details/8453532 调试程序需要打印一些消息出来,logcat不好用的话就很麻烦了。这个问题折腾了好久,为啥就是不出来呢? 上网找了很多解决办法: 重启eclipse 重启adb 重启…

17:文字排版

17:文字排版 查看提交统计提问总时间限制: 1000ms内存限制: 65536kB描述给一段英文短文,单词之间以空格分隔(每个单词包括其前后紧邻的标点符号)。请将短文重新排版,要求如下: 每行不超过80个字符;每个单词…

解决AttributeError: 'str' object has no attribute 'decode'报错问题

顺着报错文件点进去,找到query query.decode(errors‘replace’) 将decode修改为encode即可

解决python中html 代码被注释掉 依旧被解释导致报错ERROR:tornado.access:500 GET /home (xxx.xxx.xxx.xxx)

ERROR:tornado.access:500 GET /home (xxx.xxx.xxx.xxx) 注释的是Html代码,是给浏览器看的。 Html里的代码还是要执行。注释python代码用{# #}

springMvc 传子 bean 中有bean

2019独角兽企业重金招聘Python工程师标准>>> bean 类型 如下 1. json 字符串 $.ajax({ url :${ctx}/test/testData/f1?bookjava, type: post, dataType : "json", con…

关于地图中轨迹的平滑移动的实现

很多人应该都有类似的经历,叫完车,想看看车离我还有多远距离?但手机屏幕上的车不是一动不动,就是一跳一跳的漂移。 目前市面上大多产品“轨迹平滑移动”做的并不好。 市面上只有快的打车和一号专车实现了平滑移动,那…

查看centos中的用户和用户组

1、用户列表文件:/etc/passwd/ 2、用户组列表文件:/etc/group 3、查看系统中有哪些用户: cut -d : -f 1 /etc/passwd 4、查看可以登录系统的用户: cat /etc/passwd | grep -v /sbin/nologin | cut -d : -f 1 5、查看用户操作…

Android 开源优秀 Library 推荐

之后的每月会推荐一些优秀的开源 Android libraries,不仅仅是学习,也可以方便的使用到项目中,避免重复的造轮子。 PageIndicatorView 如果你需要在 ViewPager 中指明当前处于哪个画面中,PageIndicatorView是你的不二选择。而且真…

Vue2.0王者荣耀助手

vue-gok vue2.0-王者荣耀助手 项目使用的是带玩游戏平台提供的API,由于腾讯公司王者荣耀游戏关闭了查看其它人的战绩功能,带玩平台受其影响,已将API暂时关闭,所以无法获得稳定的 DAIWAN-API-TOKEN ,所以会出现DAIWAN-API-TOKEN令…

Android mc怎么和win10联机,我的世界手机版/win10版联机完美互通方法

我的世界手机版玩家想要更加方便的操作?0.12.1更新之后,你除了能使用手柄进行方便的操作之外,现在你能完全摆脱小屏幕蹩脚的操作了!win10版在9月9日进行了重大更新,我们能直接使用win10的电脑玩我的世界,而…

十大基础算法

做为程序员,以下着十大10大基础实用算法是必须知道的。

android加法服务类,iOS越来越像Android:苹果简单做加法远离精致

原标题:iOS越来越像Android:苹果简单做加法远离精致刚刚结束的WWDC2016的主题演讲中,苹果为我们带来了最新的iOS 10系统,官方称本次iOS 10的推出有着多大10项的重要更新,在用户体验、界面、Siri、地图以及音乐方面都有着不少的变化…