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指向的内存地址的数据发生了变化;
由此得出:所谓的值传递跟引用传递归根结底的区别在于,
每当对指向常量池的数据进行改变的时候,是先去寻找你所要变化的值,如果存在,直接指向;如果不存在,新建一个,直接指向。这样操作的结果是:原来的值依旧存在于常量池之中(常量池中的数据是共享的)
但是对于栈中的数据,则是直接在对应的内存地址中进行数据改变,这样会使得原数据发生变化。