JAVA到底有没有引用传递???

飘过的小牛 2013-11-23 01:05:40
最近复习《head first java》时候,看到书上写到:

在JAVA中所传递的所有东西都是值,但此值是变量所携带的值。引用对象的变量所携带的是远程空城而不是对象本身。

我感觉意思好像是在说:JAVA只存在值传递,根本不存在引用传递(和C++划分的特别清楚)。但是我在google上一搜,发现很多文章讲的都是”JAVA的值传递和引用传递..."这样的文章,于是就有了下面的疑问。

我个人理解是这样的:

对于JAVA来说,参数传值分为两种情况:
1. 基本类型:这个传值肯定是按照“值传递”来进行的,C/C++也是相同的,除非你指定int &这样的引用
2. 引用类型:这个就比较纠结了,因为你传值后,会复制一个引用到实参所指向的对象,你对对象的操作会同时影响实参和形参,那么,这个到底算是“值传递”还是“引用传递”呢?

疑问如下:
我们知道,“值传递”是不会影响到实参的。“引用传递”就相当于传递地址,其对引用对象的操作是实参/形参同时影响的。那么,在传递参数时传递一个引用,先复制一个引用指向实参对象,我个人理解这个复制操作符合“值传递”的概念,但是复制后,对指向对象的操作又会切实改变实参指向的对象,这明显是“引用传递”的特征。然后,我就傻傻分不清楚了。。。。。

求对这方面有深刻认识的高手解答,谢谢~
...全文
823 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
yktd26 2013-11-28
  • 打赏
  • 举报
回复 1
只有值传递, 但是数据类型有值类型和引用类型...
凝望_Ing 2013-11-28
  • 打赏
  • 举报
回复
我上午看了一篇文章,也是说的这个参数传递问题的,我感觉很容易理解,不懂的可以去看下http://blog.csdn.net/cocoa_cactus/article/details/16992091
ghw554557313 2013-11-26
  • 打赏
  • 举报
回复
引用 17 楼 ghw554557313 的回复:
应用传递和值传递都有 这个贴结了吧
引用
ghw554557313 2013-11-26
  • 打赏
  • 举报
回复
应用传递和值传递都有 这个贴结了吧
爪哇三郎 2013-11-26
  • 打赏
  • 举报
回复
这个问题在《practice java 》中第一个为我们解答的就是,你可以自己去看看
七伤拳 2013-11-26
  • 打赏
  • 举报
回复
给你引用一段编程随想的博文: ★传参的问题   引用类型(在函数调用中)的传参问题,是一个相当扯的问题。有些书上说是传值,有些书上说是传引用。搞得Java程序员都快成神经分裂了。所以,我们最后来谈一下“引用类型参数传递”的问题。   还是拿刚才的例子,假设现在要把刚才创建的那一坨字符串打印出来,我们会使用如下语句: System.out.println(str); 这个语句又是什么意思捏?这时候就两说了。   第一种理解: 可以认为传进函数的是str这个指针,指针说白了就是一个地址的值,说得再白一点,就是个整数。按照这种理解,就是传值的方式。也就是说,参数传递的是指针本身,所以是传值的。   第二种理解: 可以认为传进去的是StringBuffer对象,按照这种理解,就是传引用方式了。因为我们确实是把对象的地址(也就是引用)给传了进去。   费了这么多口水,其实不论是传引用还是传值,都可以讲得通,关键取决于你是如何看待参数所传递的东西。这就好比量子力学中“光的波粒二象性”,如果你以粒子的方式去测量它,它看起来像粒子;如果你以波动的方式去观测它,它看起来像波动。假如你不太懂量子力学,前面这话当我没说 :-) 出处:http://program-think.blogspot.com/2009/03/java-reference-types-detail.html
飘过的小牛 2013-11-26
  • 打赏
  • 举报
回复
不好意思,原理我明白了。但是,我还是想问一下: JAVA是不是只有值传递?(所谓的引用传递,说白了就是堆中对象的别名,其实都是一个东西嘛。所以传递的也是”内存地址这个值“,是不是也算值传递) 那么,在C++中的为什么就有”值传递“和”引用传递“两种呢? 我个人还是倾向于基本类型是”值传递“,引用类型是”引用传递“
飘过的小牛 2013-11-26
  • 打赏
  • 举报
回复
引用 12 楼 u012677436 的回复:
[quote=引用 楼主 niushuai666 的回复:]我个人理解这个复制操作符合“值传递”的概念,但是复制后,对指向对象的操作又会切实改变实参指向的对象,这明显是“引用传递”的特征。然后,我就傻傻分不清楚了。。。
这里. 对象的传递. 例如.对象1的两部份.内存地址--A 内存--a 对象2 = 对象1 那么对象2的两部份是 内存地址--A副本 内存a 它们只是传递了栈里的内存地址. 对象1与2 是共用一个内存空间的.而不是对象2重新开辟一个同样大小的空间.. 你修改A副本,直接影响到 内存a 就好像一个银行账户.取钱方式有一本存折,一张银行卡..无论你用哪种方式取钱.都会影响到账户余额. 所以这不是"引用传递". 只是内存地址的值的传递. [/quote] 嗯,非常感谢。看了你的解释我明白了。我总结一下就是: 基本类型,复制的就是一个值,这个值是实参的副本,你对这个副本的任何操作都不会影响到实参。 引用类型,它传递的也是值,这个值是引用的内存地址的复制(相当于两个引用指向了堆中同一对象),那么你对这个对象的操作会同时影响实参和形参。 所以,基本类型就是”值传递“,而引用类型就是”引用传递“。
wct357110558 2013-11-26
  • 打赏
  • 举报
回复
有引用啊。。。 只是说法不一样了而已啊。。
_KyLeo 2013-11-26
  • 打赏
  • 举报
回复
学了JAVA,还真没认真区分过这个问题,一直把它当作和C语言的指针来处理,只是JAVA里面没有指针这一概念而已
最勇敢的鸟 2013-11-26
  • 打赏
  • 举报
回复
引用 1 楼 kingofvc 的回复:
分两种情况, 第一种 基础类型, 这个java里不管是效果还是形式, 只有值传递 第二种 对象, 这个表现比较奇怪, 效果其实更像是指针而不是引用。而指针,说白了是值传递,传递的是地址值。 java这边也一样, 只是没有指针的形式罢了。
这个是正解
u012960034 2013-11-26
  • 打赏
  • 举报
回复
java肯定有引用链接
飘过的小牛 2013-11-26
  • 打赏
  • 举报
回复
引用 15 楼 iLdf 的回复:
给你引用一段编程随想的博文: ★传参的问题   引用类型(在函数调用中)的传参问题,是一个相当扯的问题。有些书上说是传值,有些书上说是传引用。搞得Java程序员都快成神经分裂了。所以,我们最后来谈一下“引用类型参数传递”的问题。   还是拿刚才的例子,假设现在要把刚才创建的那一坨字符串打印出来,我们会使用如下语句: System.out.println(str); 这个语句又是什么意思捏?这时候就两说了。   第一种理解: 可以认为传进函数的是str这个指针,指针说白了就是一个地址的值,说得再白一点,就是个整数。按照这种理解,就是传值的方式。也就是说,参数传递的是指针本身,所以是传值的。   第二种理解: 可以认为传进去的是StringBuffer对象,按照这种理解,就是传引用方式了。因为我们确实是把对象的地址(也就是引用)给传了进去。   费了这么多口水,其实不论是传引用还是传值,都可以讲得通,关键取决于你是如何看待参数所传递的东西。这就好比量子力学中“光的波粒二象性”,如果你以粒子的方式去测量它,它看起来像粒子;如果你以波动的方式去观测它,它看起来像波动。假如你不太懂量子力学,前面这话当我没说 :-) 出处:http://program-think.blogspot.com/2009/03/java-reference-types-detail.html
第二种理解明显的错的,str只是一个引用。new StringBuffer()才是一个对象。
飘过的小牛 2013-11-26
  • 打赏
  • 举报
回复
OK。看了很多高手的解答+网上搜资料。总结如下: JAVA确实只存在:”值传递“ 基本类型:”值传递“,无异议 引用类型:内存地址传递。首先内存地址是一个值,而我们当成参数时,实际会生成这个值(内存地址)的副本,它和实参指向了堆上相同的对象,而不是在堆上新建一个对象。说白了,还是值的复制。所以,引用类型本质上说还是”值传递“ ================================================================================= 引用《Head First Java》P78页的原文: 问:如果想要传入的参数是对象而不是primitive主数据类型会怎样? 答:你会在稍后的章节中知道有关这件事情更多的细节,但是你早就知道答案了。在Java中所传递的所有东西都是值,但此值是变量所携带的值。还有,引用对象的变量所携带的是远程控制而不是对象本身。若你对方法传入参数,实际上传入的是远程控制的拷贝。 ================================================================================= 1. 上文中,primitive主数据类型就是基本类型(8大类) 2. 红色字体清晰指出”Java只有值传递“ 3. 远程控制就是内存地址 4. 远程控制的拷贝,很明显值的复制,所以是”值传递“ ================================================================================= 如果各位还有异议,请明确指出出处。最好是摘抄原文方便大家查看。当然,也欢迎有根据的提出自己的见解。我觉得这个问题应该搞清楚,所以,如果有人能把C++为什么同时有”值传递“和”引用传递“,而JAVA只有”值传递“(或者JAVA也同时有”值传递“和”引用传递“)的原因讲清楚,我想很多人都会或偶然开朗的。谢谢~~~
Duke__ 2013-11-25
  • 打赏
  • 举报
回复
引用 楼主 niushuai666 的回复:
我个人理解这个复制操作符合“值传递”的概念,但是复制后,对指向对象的操作又会切实改变实参指向的对象,这明显是“引用传递”的特征。然后,我就傻傻分不清楚了。。。
这里. 对象的传递. 例如.对象1的两部份.内存地址--A 内存--a 对象2 = 对象1 那么对象2的两部份是 内存地址--A副本 内存a 它们只是传递了栈里的内存地址. 对象1与2 是共用一个内存空间的.而不是对象2重新开辟一个同样大小的空间.. 你修改A副本,直接影响到 内存a 就好像一个银行账户.取钱方式有一本存折,一张银行卡..无论你用哪种方式取钱.都会影响到账户余额. 所以这不是"引用传递". 只是内存地址的值的传递.
Duke__ 2013-11-25
  • 打赏
  • 举报
回复
引用 8 楼 niushuai666 的回复:
[quote=引用 7 楼 u012677436 的回复:] 传递 传递的都是栈里的的值,只是有些栈里面的是值.有的是内存地址 基本类型的栈 是它的本身. 传递时.传递的是本身的副本.所以对副本修改原响不了本身 引用类型的栈 是一个内存地址.传递时..传递的是内存地址的副本..原内存地址与副本都指向同一内存. 所以.修改副本指向内存的内容时.会影响到原内存地址指向的内存 基本类型进行传递的时候是值的 副本,基本类型的副本是一个栈(栈内存里存的是基本类型的本身),所以对栈的副本进行修改不会影响原件 引用类型进行传递的时候是值的 副本,引用类型的副本是一个内存地址(栈),所以副本和原件都是都指向同一块内存堆空间
感觉你的说法很有道理,但不知道你说的“传递的都是栈里的的值”是不是正确的。请问有出处吗?[/quote] JAVA传递的只有值,这个是肯定的了.传递的都是栈里的的值.这句你可以分析一下JAVA的存储机制.它出处是我总结的.哈哈.不知道有哪些书说到. 我博客里也写了一篇简单的值的传递的笔记http://blog.csdn.net/java_jh/article/details/16921357
只是_曾经 2013-11-25
  • 打赏
  • 举报
回复
引用 7 楼 u012677436 的回复:
传递 传递的都是栈里的的值,只是有些栈里面的是值.有的是内存地址 基本类型的栈 是它的本身. 传递时.传递的是本身的副本.所以对副本修改原响不了本身 引用类型的栈 是一个内存地址.传递时..传递的是内存地址的副本..原内存地址与副本都指向同一内存. 所以.修改副本指向内存的内容时.会影响到原内存地址指向的内存 基本类型进行传递的时候是值的 副本,基本类型的副本是一个栈(栈内存里存的是基本类型的本身),所以对栈的副本进行修改不会影响原件 引用类型进行传递的时候是值的 副本,引用类型的副本是一个内存地址(栈),所以副本和原件都是都指向同一块内存堆空间
+1
只是_曾经 2013-11-25
  • 打赏
  • 举报
回复
你对值的理解有些偏差,java的引用传递只是传递了一个地址,而不是整个对象的值。 而值传递是传递整个数据的值。 反正引用传递说破大天也不是值传递,按你的理解,可能是觉得引用传递这个叫法不准确吧。
飘过的小牛 2013-11-25
  • 打赏
  • 举报
回复
引用 7 楼 u012677436 的回复:
传递 传递的都是栈里的的值,只是有些栈里面的是值.有的是内存地址 基本类型的栈 是它的本身. 传递时.传递的是本身的副本.所以对副本修改原响不了本身 引用类型的栈 是一个内存地址.传递时..传递的是内存地址的副本..原内存地址与副本都指向同一内存. 所以.修改副本指向内存的内容时.会影响到原内存地址指向的内存 基本类型进行传递的时候是值的 副本,基本类型的副本是一个栈(栈内存里存的是基本类型的本身),所以对栈的副本进行修改不会影响原件 引用类型进行传递的时候是值的 副本,引用类型的副本是一个内存地址(栈),所以副本和原件都是都指向同一块内存堆空间
感觉你的说法很有道理,但不知道你说的“传递的都是栈里的的值”是不是正确的。请问有出处吗?
ZeqLi 2013-11-24
  • 打赏
  • 举报
回复
Java 传一般变量的时候使用的是“值传递” Java 传对象(Object)的时候使用的是“引用传递”
加载更多回复(6)

67,514

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧