java函数参数传递在堆、栈、常量池的理解(容易理解)

    xiaoxiao2021-03-25  27

    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放进去③将栈中的引用指向堆中的内存地址

    [java]  view plain  copy  print ? public class C1215_1 {       public static void main(String[] args) {           String a = "lizhi";           String a1 = "lizhi";           String b = new String("lizhi");            StringBuffer c = new StringBuffer("lizhi");           System.out.println(a == a1);           System.out.println(a == b);           change(a,b,c);           System.out.println("a :"+a+"\n"+"b :"+b+"\n"+"c :"+c);       }       public static void change(String a,String b,StringBuffer c){           a = "change";           b = "change";           c.append("change");       }   }   结果是:

    [html]  view plain  copy  print ? true   false   a :lizhi   b :lizhi   c :lizhichange   由上面的代码就可以看得出来;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指向的内存地址的数据发生了变化;

    由此得出:所谓的值传递跟引用传递归根结底的区别在于,

    每当对指向常量池的数据进行改变的时候,是先去寻找你所要变化的值,如果存在,直接指向;如果不存在,新建一个,直接指向。这样操作的结果是:原来的值依旧存在于常量池之中(常量池中的数据是共享的)

    但是对于栈中的数据,则是直接在对应的内存地址中进行数据改变,这样会使得原数据发生变化。

    转载请注明原文地址: https://ju.6miu.com/read-50055.html

    最新回复(0)