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语言,很详细哦(5页珍藏版)》请在人人文库网上搜索。1、求迷宫问题就是求出从入口到出口的路径。在求解时 , 通常用的是 “穷举求解”的方法 ,即从入口出发 ,顺某一方向向…

模块概述

概述 目前代码比较少,写在一个文件中还体现不出什么缺点,但是随着代码量越来越多, 代码就越来越难以维护 为了解决难以维护的问题,我们把很多相似功能的函数分组,分别放到不同的文件中取。这样每个文件所包含的内容相…

【MySQL】PREPARE 的应用

简单的用set或者declare语句定义变量,然后直接作为sql的表名是不行的,mysql会把变量名当作表名。在其他的sql数据库中也是如此,mssql的解决方法是将整条sql语句作为变量,其中穿插变量作为表名,然后用sp_executesql调用…

简历要求中“ 扎实的JAVA基础”的学习方法

最近在头条看到一篇关于Java基础学习的文章,感觉写的很不错,分享一下,希望对大家有帮助 什么东西算作Java基础?学到什么程度才算扎实? 这些问题的答案,LZ已经用文言文告诉你了,咳咳,…

C++11 tuple的使用

多少分转载于:https://www.cnblogs.com/DswCnblog/p/6524832.html

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

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

解决bash: mysql: command not found 的方法【linux mysql命令 】

linux下,在mysql正常运行的情况下,输入mysql提示: mysql command not found 遇上-bash: mysql: command not found的情况别着急,这个是因为/usr/local/bin目录下缺失mysql导致,只需要以下方法即可以解决: …

堆和栈的区别(经典干货)

一、预备知识—程序的内存分配 一个由C/C编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其 操作方式类似于 数据结构 中的栈。 2、堆区(he…

Strus2中关于ValueStack详解

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

Airbnb React/JSX 编码规范

Airbnb React/JSX 编码规范算是最合理的React/JSX编码规范之一了内容目录基本规范Class vs React.createClass vs stateless命名声明模块代码对齐单引号还是双引号空格属性Refs引用括号标签函数/方法模块生命周期isMountedBasic Rules 基本规范每个文件只写一个模块.但是多个无…

Mysql数据库使用总结

mysql数据库使用总结 本文主要记录一些mysql日常使用的命令,供以后查询。 1.更改root密码 mysqladmin -uroot password yourpassword 2.远程登陆mysql服务器 mysql -uroot -p -h192.168.137.10 -P3306 3.查询数据库 show databases; 4.进入某个数据库 use databa…

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

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

Eclipes导入的项目中的中文都是乱码的解决办法

把项目导入Eclipse时,里边的中文全是乱码,试了很多方法,最终总结一下! eclipse之所以会出现乱码问题是因为eclipse编辑器选择的编码规则是可变的。一般默认都是UTF-8或者GBK,当从外部导入的一个工程时,如果…

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

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

CentOS下的Mysql的安装和使用

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

NOIP模拟题——神秘大门

【题目描述】最近小K大牛经过调查发现,在WZland的最南方——WZ Antarctica 出现了奇怪的磁场反应。为了弄清楚这一现象,小K 大牛亲自出马,来到了WZ Antarctica。小K大牛发现WZ Antarctica 出现了一道神秘的大门。人总有好奇心,小K…

大学c语言程序设计大赛,关于举办宁夏大学第二届C语言程序设计大赛的通知

各学院:根据学校《关于进一步加强基础课教学改革的意见》(宁大校发〔2008〕178号)、《关于加强学生创新精神和创新能力培养的实施意见》(宁大校发〔2008〕75号)的有关文件精神,经研究决定举办宁夏大学第二届C语言程序设计大赛,从中选拔出优秀…

Android中创建自己的对话框

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

django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11

搭建Django2.0Python3MySQL5时同步数据库时报错: django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None 解决办法: 找到Python安装路劲下的Python36-32\Lib\site-packages\django\db\backend…