• 值传递:pass by value(按值传递) 和 pass by reference(引用传递)-[all]-[编程原理]


    所有的编程语言,都会讨论值传递问题。

    通过一个js示例直观认识

    //理解按值传递(pass by value)和按引用传递(pass by reference)
    //pass by value 
    var a = 1;
    var b = a; //把a赋值给b
    a = 2;//修改a值
    console.log(a,b)//返回 2 1
    
    //pass by reference
    var a = {name:"小明"};
    var b = a;
    a.name = "nike"; 
    console.log(b.name)//返回值是nike
    

    以上示例,可见,在pass by value 中,我们先定义了一个a变量初始值为1,然后定义了一个b变量,是直接把a赋值给了b,此时a,b值都是1,修改a值为2后,打印发现b值并没有被修改。这说明了一个问题:定义b变量时,var b = a,仅仅是吧a的value复制了一份给到了b, 而a,b是单独的两个变量,在内存中,是两个不同的地址。 因此仅修改a的value,b的value不受影响。

    在pass by reference中,定义了一个对象a,然后定义了一个变量b,并把a复制给b,修改a.name这个属性值为“nike”,我们发现打印出来的b值发生了改变。 这说明:定义b变量时,var b = a,不仅仅是简单的复制,而是把{name:"小明"}这个object同时指向了b。 即a,b这两个变量都同时指向了同一个对象,在内存中,是同一个内存地址。因此在修改其中任何一个的时候,另一个当然也会改变。

    总结

    总结:对于这两种传递方式,我们从内存上去理解就容易理解的多。

    按值传递(pass by value):多个变量,值相同,内存地址不同,有多个内存,因此各个值的修改互不影响。

    引用传递(pass by reference):多个变量,指向同一个内存地址,修改任意一个,全部改动。

    原理深入

    Java把内存划分成两种:一种是栈内存,一种是堆内存。

    在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分> > 配的内存空间,该内存空间可以立即被另作他用。

    堆内存用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或对象后,还可以在栈中定义 一个特殊的变量,让栈中这个变量的取值等于数组或对象> > 在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。 引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。

    如果参数是基本类型,传递的是基本类型的字面量值的拷贝。
    如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。

    这两句已经很清楚的解释了JAVA是如何传递方法参数的,即传递值的拷贝(我的理解为在调用方法者的栈帧中,拷贝一份值(不论是基本类型还是地址)到操作数栈中,然后将其推出,赋值给方法栈帧的局部变量中)

    参考:link1 link2

  • 相关阅读:
    第九篇:网络编程
    第十篇:并发编程
    Python-GIL 进程池 线程池
    Python-生产者消费模型 线程
    Python-互斥锁 进程间通讯
    第八篇:异常处理
    第六篇:面向对象
    第四篇:模块与包
    【转】英语中的并列连词,只知道 and 和 but?11组并列连词,一篇搞定!
    【转】英语中的从属连词,28个,一篇搞定(句子结构2)
  • 原文地址:https://www.cnblogs.com/jaycethanks/p/12073542.html
Copyright © 2020-2023  润新知