摘要:有种流行的观点说的另外一个特殊之处在于,在方法调用传参数时,是按值传递的,其他普通对象是引用传递。然而这种说法是大大错误的,至少是完全误解了值传递和引用传递的概念。方法调用传参只有一种传递就是值传递。
上篇文章说到Java的String是比较特殊的对象,它是不可变的。
有种流行的观点说String的另外一个特殊之处在于,在方法调用传参数时,String是按值传递的,其他普通对象是引用传递。
然而这种说法是大大错误的,至少是完全误解了值传递和引用传递的概念。
值传递和引用传递的概念:
值传递在发生的时候会为callee参数新建一个变量,新的变量存储的值与实参的值一致。
引用传递时,callee并不为参数变量新建对象,而是直接使用caller里的实参变量。
举例来说:
public static void main(String[] args) { Object obj = new Object(); PassValue(obj); } private static void PassValue(obj) { String s = obj.toString(); }
如果是值传递,main函数中的obj和PassValue方法中的o是两个独立的变量,只是他们的值相等。
如果是引用传递,main函数中的obj和PassValue方法中的o根本就是同一个变量。
如果文字看的有点晕,请看手画图:
Surface上画的有点抽象,包容一下。
打个比方,我要给你传递一些悄悄话,我把信息放到一个变量给你————一个txt文档。我和你之间有两种方式:
你直接访问我们电脑,以后你看我电脑上的txt文档————咱俩共享变量;
你也可以复制一份txt到你的电脑,以后你看你自己电脑上的那份txt文档————你和我各用各的变量。
在代码里,第一种方式就是引用传递,第二种就是值传递。
还是接着例子,我给你传递的txt有可能会有两种形式:
直接在txt里写着我要说的话"我看好你哟";
在txt里只有一个url,url指向一个网站,网站里写着"我看好你哟".
第一种形式就是传递基本类型参数,第二张是传递引用类型参数。
所以,这里有四种组合,我们一一来看:
引用传递传递基本类型参数。你把txt文档里的话改为可是我并不看好你啊,我看得到,因为你改的是我电脑上的txt文档。
引用传递传递引用类型参数。你直接改txt里的url地址,或者你不改url,而且去改url指向的网站的内容,我都能看到;
值传递传递基本类型参数。你把txt文档里的话改为可是我并不看好你啊,我看不到,因为你改的是你电脑上的那份txt。
值传递传递引用类型参数。你直接改txt里的url地址,我看不到,因为你改的是你电脑上的那份txt。你改url指向的网站的内容,我看的到。
对应代码里,当传递参数为引用类型时,例子中改url地址就是在callee中改变变量指向的堆的位置,即指向另一个对象;改url指向的内容,即是改变量指向的那个对象的内容。当传递参数为基本类型参数时,例子中改变txt文档内容,就是callee改变参数的值。
搞清楚概念了,怎么想都能把问题想明白。
回到开头的问题,有人说String特殊,特殊在哪?无非有人发现String在callee里没法被改,但是其他普通引用类型对象可以在callee里被改动。现在我们可以说,这是废话。因为String是不可变类,它的内容一经创建再不能变,别说你通过参数传递,你就是在主函数里,你照样没法改String对象的内容。所以String在callee中无法被改动和参数传递方式压根没有关系,这是String的不可变性问题,完全两码事。
可以看出来,如果参数传递的是引用变量,那么无论是哪种传递方式,callee对对象内容的改动,对caller都是可见的。除非你这对象压根不能改。
Java方法调用传参只有一种传递就是值传递。这并没有道理可讲,实现如此。
参考:
[1] https://en.wikipedia.org/wiki...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/77082.html
摘要:我们在处新创建了一个并将其引用在处传给了方法的参数该方法内部引用在处被重新赋值。如果是引用传递,那么引用在处已经被指向了新的输出应该为才对,事实上是怎样的呢事实上输出了也就是说方法改变了传入引用所指对象的值。此处注意,并非将重新分配,而是。 我们来看一个新手甚至写了多年Java的朋友都可能不是十分确定的问题: 在Java方法传参时,究竟是引用传递还是值传递? 为了说明问题, 我给出一个...
摘要:引用泛型除了方法因不能使用外部实例参数外,其他继承实现成员变量,成员方法,方法返回值等都可使用。因此,生成的字节码仅包含普通的类,接口和方法。 为什么要使用泛型程序设计? 一般的类和方法,只能使用具体的类型:要么是基本类型,要么是自定义类的对应类型;如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。----摘自原书Ordinary classes and meth...
摘要:它对数组和对象使用按值传递,但这是在的共享传参或拷贝的引用中使用的按值传参。例如在这里,变量和值在执行期间存储在堆栈中。返回值这是可选的,函数可以返回值,也可以不返回值。变量被推入堆栈,从而在执行时成为的副本。 这是专门探索 JavaScript 及其所构建的组件的系列文章的第 22 篇。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 如果你错过了前面的章节,可...
摘要:它对数组和对象使用按值传递,但这是在的共享传参或拷贝的引用中使用的按值传参。例如在这里,变量和值在执行期间存储在堆栈中。返回值这是可选的,函数可以返回值,也可以不返回值。变量被推入堆栈,从而在执行时成为的副本。 这是专门探索 JavaScript 及其所构建的组件的系列文章的第 22 篇。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 如果你错过了前面的章节,可...
摘要:接下了,我们调用方法,来尝试改变的值以此验证中的传值方式。我们将作为实参传给方法,形参来接受这个实参,在这里就体现出了两种传参方式的不同。中只有值传递这一种方式,只不过对于引用类型来说,传递的参数是对象的引用罢了。 前言 这几天在整理java基础知识方面的内容,对于值传递还不是特别理解,于是查阅了一些资料和网上相关博客,自己进行了归纳总结,最后将其整理成了一篇博客。 值传递 值传递是指...
阅读 1874·2021-11-24 11:16
阅读 3239·2021-09-10 10:51
阅读 3139·2021-08-03 14:03
阅读 1239·2019-08-29 17:03
阅读 3221·2019-08-29 12:36
阅读 2178·2019-08-26 14:06
阅读 475·2019-08-23 16:32
阅读 2618·2019-08-23 13:42