java函数参数传递在堆、栈、常量池的理解(容易理解)
来源:互联网 发布:历史网络课答案 编辑:程序博客网 时间:2024/06/15 18:50
http://www.cnblogs.com/gw811/archive/2012/10/18/2730117.html
先学习了解上面的关于Java内存管理的各个内存区域的功能:
关于JAVA值传递和引用传递首先得了解栈和堆以及常量池的基本概念:
举个栗子:
String s = ‘"lizhi";
直接初始化一个String类型的变量的内部实现步骤:①JVM首先在栈中初始化一个String类型的引用 ②然后去常量池中寻找是否存在lizhi这个字符串③如果存在,则将栈中的引用直接指向常量池的lizhi,如果不存在,则在常量池新建一个lizhi,并用栈中的引用指向这个lizhi。
String t = new String("newlizhi");
使用new初始化一个String类型的变量的内部实现步骤:①JVM首先在栈中初始化一个String类型的引用②然后在堆中开辟一块新的内存空间,并将lizhi放进去③将栈中的引用指向堆中的内存地址
结果是:由上面的代码就可以看得出来;a和a1都是指向常量池中的同一块内存 地址,所以相等。然后对于值传递和引用传递,我的理解是:所谓的值传递和引用传递,传递的都只是这个数据的栈中的引用的副本;
就还是以上面的栗子来说:当传入的参数是a时,实际上是传入了一个a指向(指向常量池中"lizhi")的副本。a(副本) = "change"这句话的实现步骤跟上面的初始化a是一样的:①在常量池中寻找是否存在change这个字符串,如果存在,则直接指向它;如果不存在,则新建change然后指向它;这时候,无论存不存在这个change,原来常量池之中的lizhi都是依然存在的,且a依旧是指向lizhi的;
当传入的参数是b时,基本步骤跟上面一样,但是有一点不同的是,b指向原来是指向堆的,但是b的副本却是指向常量池的。
当传入的参数是c是,传入的c的副本跟c都是指向栈中的lizhi的内存地址的;当对其进行c.append"change"')操作时,则是直接对其栈中的lizhi的内存进行操作,改变的是lizhi内存地址之中的数据;且因为c也是指向这块内存,所以方法执行完毕,c指向的内存地址的数据发生了变化;
由此得出:所谓的值传递跟引用传递归根结底的区别在于,
每当对指向常量池的数据进行改变的时候,是先去寻找你所要变化的值,如果存在,直接指向;如果不存在,新建一个,直接指向。这样操作的结果是:原来的值依旧存在于常量池之中(常量池中的数据是共享的)
但是对于栈中的数据,则是直接在对应的内存地址中进行数据改变,这样会使得原数据发生变化。
- java函数参数传递在堆、栈、常量池的理解(容易理解)
- JAVA中函数调用参数传递的理解(值传递和引用传递的理解)
- 函数参数传递的理解!
- 深入理解java中栈,堆常量池。。
- 对于Java中函数参数传递的理解
- JAVA中堆、栈、常量池以及equal,==,hashcode的理解
- JAVA中堆、栈、常量池以及equal,==,hashcode的理解
- java中关于栈、堆、常量池介绍和关于String类的理解
- java中栈.堆.常量池和关于String类的理解
- Java:理解Java中函数参数传递的【按值传递】和【按引用传递】
- Java堆、栈和常量池以及相关String的详细讲解(经典中的经典)深入理解
- 关于构造函数传递参数的理解
- java常量池的理解
- java参数传递的最终理解
- 理解java常量池
- 理解Java常量池
- 理解Java常量池
- 理解Java常量池
- 155. Min Stack
- 2017年要学习的三个CSS新特性
- 将.hex文件导入到Matlab中
- SQL语句中 Case具有两种格式:简单Case函数和Case搜索函数
- JavaScript的内存泄漏
- java函数参数传递在堆、栈、常量池的理解(容易理解)
- LPCXpresso54608开发板中文用户手册
- 关于INSTALL_FAILED_MEDIA_UNAVAILABLE的处理
- Cocos2d-JS中JavaScript继承
- java 8 G1
- 在windows基于Eclipse编写hadoop时,遇到的 WARN util.NativeCodeLoader问题
- 三维空间中的几种坐标系
- 检查数据库坏块并处理
- java实现一个多线程下载工具类