理解java值传递与引用传递
1.基本类型和引用类型在内存中的保存
Java中数据类型分为两大类,基本类型和对象类型。相应的,变量也有两种类型:基本类型和引用类型。
基本类型的变量保存原始值,即它代表的值就是数值本身;
而引用类型的变量保存引用值,"引用值"指向内存空间的地址,代表了某个对象的引用,而不是对象本身,
对象本身存放在这个引用值所表示的地址的位置。
基本类型包括:byte,short,int,long,char,float,double,Boolean,returnAddress,
引用类型包括:类类型,接口类型和数组。
相应的,变量也有两种类型:基本类型和引用类型。
2.变量的基本类型和引用类型的区别
基本数据类型在声明时系统就给它分配空间:
| 1 2 | inta;a=10;//正确,因为声明a时就分配了空间 | 
引用则不同,它声明时只给变量分配了引用空间,而不分配数据空间:
| 1 2 3 4 5 6 7 | Date date;//执行实例化,开辟数据空间存放Date对象,然后把空间的首地址传给today变量 //date=new Date();//如果注释掉上一步操作//The local variable date may not have been initialized//也就是说对象的数据空间没有分配date.getDate(); | 
看一下下面的初始化过程,注意"引用"也是占用空间的,一个空Object对象的引用大小大概是4byte:
| 1 2 3 | Date a,b; //在内存开辟两个引用空间a = newDate();//开辟存储Date对象的数据空间,并把该空间的首地址赋给ab = a; //将a存储空间中的地址写到b的存储空间中 | 
3.引用传递和值传递
这里要用实际参数和形式参数的概念来帮助理解,
值传递:
方法调用时,实际参数把它的值传递给对应的形式参数,函数接收的是原始值的一个copy,此时内存中存在两个相等的基本类型,即实际参数和形式参数,后面方法中的操作都是对形参这个值的修改,不影响实际参数的值。
引用传递:
也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,函数接收的是原始值的内存地址;
在方法执行中,形参和实参内容相同,指向同一块内存地址,方法执行中对引用的操作将会影响到实际对象。
看一个例子:
| 1 2 3 | classMyObj{    publicintb=99;} | 
分别传参int和对象类型:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | publicclassReferencePkValue2 {        publicstaticvoidmain(String[] args) {         ReferencePkValue2 t = newReferencePkValue2();         inta=99;         t.test1(a);//这里传递的参数a就是按值传递         System.out.println(a);                MyObj obj=newMyObj();         t.test2(obj);//这里传递的参数obj就是引用传递        System.out.println(obj.b);    }         publicvoidtest1(inta){         a=a++;        System.out.println(a);        }         publicvoidtest2(MyObj obj){         obj.b=100;        System.out.println(obj.b);        }} | 
输出是:
99         
99            
100          
100           
可以看到,int值没有发生变化,但是在test2方法中对obj类做的修改影响了obj这个对象。
这里要特殊考虑String,以及Integer、Double等几个基本类型包装类,它们都是immutable类型,
因为没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待,可以认为是和基本数据类型相似,传值操作。
看下面的例子:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | publicclassReferencePkValue1 {    publicstaticvoidmain(String[] args){        ReferencePkValue1 pk=newReferencePkValue1();        //String类似基本类型,值传递,不会改变实际参数的值        String test1="Hello";        pk.change(test1);        System.out.println(test1);                //StringBuffer和StringBuilder等是引用传递        StringBuffer test2=newStringBuffer("Hello");        pk.change(test2);                System.out.println(test2.toString());    }        publicvoidchange(String str){        str=str+"world";    }        publicvoidchange(StringBuffer str){        str.append("world");    }} | 
输出是:
Hello        
Helloworld             
对String和StringBuffer的操作产生了不同的结果。
4.结论
结合上面的分析,关于值传递和引用传递可以得出这样的结论:
(1)基本数据类型传值,对形参的修改不会影响实参;
(2)引用类型传引用,形参和实参指向同一个内存地址(同一个对象),所以对参数的修改会影响到实际的对象;
(3)String, Integer, Double等immutable的类型特殊处理,可以理解为传值,最后的操作不会修改实参对象。
理解java值传递与引用传递的更多相关文章
- 堆栈详解 + 彻底理解Java的值传递和引用传递
		本文旨在用最通俗的语言讲述最枯燥的基本知识 学过Java基础的人都知道:值传递和引用传递是初次接触Java时的一个难点,有时候记得了语法却记不得怎么实际运用,有时候会的了运用却解释不出原理,而且坊间讨 ... 
- JAVA不可变类与可变类、值传递与引用传递深入理解
		一个由try...catch...finally引出的思考,在前面已经初步了解过不可变与可变.值传递与引用传递,在这里再次深入理解. 1.先看下面一个try..catch..finally的例子: P ... 
- 理解java中的值传递与“引用传递”
		额....java中其实没有引用传递 对于引用类型 ,在调用方法后,直接拷贝了引用的副本,但是它们指向了相同的堆地址,所以看起来像引用传递,但其实是值传递,只不过传递的引用的副本. 说一说为什么Str ... 
- java是值传递还是引用传递
		首先写一个简便的Employee,以便测试使用. class Employee { private String name; public Employee(String name) { this.n ... 
- Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义
		一.Java中什么叫做引用类型变量?引用:就是按内存地址查询 比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ... 
- java中值传递和引用传递
		最近工作中使用到了值传递和引用传递,但是有点懵,现在看了下面的文章后清晰多了.一下是文章(网摘) 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public clas ... 
- Java中的值传递和引用传递
		这几天一直再纠结这个问题,今天看了这篇文章有点思路了,这跟C++里函数参数为引用.指针还是有很大区别. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里 ... 
- java的值传递和引用传递
		昨天博主在对于值传递和引用传递这里栽了一个大坑啊,导致一下午时间都浪费在这里,我们先说下值传递和引用传递java官方解释: 值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对 ... 
- java中方法的参数传递机制(值传递还是引用传递)
		看到一个java面试题: 问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递.Java 编程语言只有值传递参 ... 
随机推荐
- [ExtJS5学习笔记]第十七节 Extjs5的panel组件增加accodion成为折叠导航栏
			本文地址:http://blog.csdn.net/sushengmiyan/article/details/39102335 官方例子:http://dev.sencha.com/ext/5.0.1 ... 
- 【ShaderToy】跳动的心❤️
			写在前面 注:如果你还不了解ShaderToy,请看开篇. 作为ShaderToy系列的第一篇,我们先来点简单的.下面是效果: (CSDN目前不能传gif文件了,暂时空缺,可以看下面的原shader效 ... 
- 如何查看Android设备上的分区信息
			Android设备上,一般都会存在一块eMMC存储芯片来存放系统和用户数据,甚至部分的引导程序. 一般设备出厂时,各个厂商都会将这块存储芯片分成很多的分区,每个分区内存放不同的内容.具体分区的布局每个 ... 
- UNIX网络编程——信号驱动式I/O
			信号驱动式I/O是指进程预先告知内核,使得当某个描述符上发生某事时,内核使用信号通知相关进程. 针对一个套接字使用信号驱动式I/O,要求进程执行以下3个步骤: 建立SIGIO信号的信号处理函数. 设置 ... 
- Cocos2D iOS之旅:如何写一个敲地鼠游戏(十):创建游戏逻辑
			大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ... 
- 关于大数据时代传统商业存储的思考: 中心存储 VS 分布式存储
			尊重原创,转载请注明出处:http://anzhan.me ; http://blog.csdn.net/anzhsoft 今天和我们部门的老大1*1, 大家面对面沟通了一下到新的项目组的想法.而且也 ... 
- 打Patch实践
			一.找到相应PATCH 确认系统已安装模块版本. SELECTapp.application_short_name, app.application_name, pi.patch_level FR ... 
- Eclipse 快捷方式 指定 固定 workspace
			右点击Eclipse快捷键,然后点击属性, 把目标(target)内容修改如下: clipse -data c:\myworkspace -vm c:\ j2sdk1.5\jre\bin\javaw ... 
- iOS中 MPMoviePlayer 实现视频音频播放 作者:韩俊强
			ios播放视频文件一般使用 MPMoviePlayerViewController 和 MPMoviePlayerController.前者是一个view,后者是个Controller.区别就是 MP ... 
- Leetcode_67_Add Binary
			本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/40480151 Given two binary strin ... 
