您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
Java深入学习系列之值传递Or引用传递?
 
作者: 夏磊洲 来源: .51cto 发布于 2016-9-27
  2035  次浏览      19
 

Java深入学习系列之值传递Or引用传递?

在Java方法传参时,究竟是引用传递还是值传递?关于Java里值传递还是引用传递,至少从表现形式上来看,两种观点都有支撑的论据。Java内部方法传参不是引用传递,而是引用本身的"值"的传递,归根结底还是值传递。

我们来看一个新手甚至写了多年Java的朋友都可能不是十分确定的问题:

在Java方法传参时,究竟是引用传递还是值传递?

为了说明问题, 我给出一个非常简单的class定义:

下面在阐明观点时,可能会多次用到该类。

关于Java里值传递还是引用传递,至少从表现形式上来看,两种观点都有支撑的论据。下面我来一一分析:

观点1:引用传递

理由如下:先看一段代码

上述示例,输出结果为"c",而不是"c"。

我们在line AAA处新创建了一个Object Foo并将其引用fooRef在line BBB处传给了方法modifyReference()的参数cRef, 该方法内部处理后,fooRef指向的Object中的值从"a"变成了"c", 而引用fooRef还是那个引用, 因此,我们是否可以认为,在line BBB处发生了引用传递?

先留着疑问,我们继续往下看。

观点2:值传递

继续看一段代码

上述示例,输出结果为"a", 而不是"b"。

我们在line AAA处新创建了一个Object Foo并将其引用fooRef在line EEE处传给了方法changeReference()的参数aRef, 该方法内部引用aRef在line DDD处被重新赋值。如果是引用传递,那么引用aRef在line EEE处已经被指向了新的Object, 输出应该为"b"才对,事实上是怎样的呢?事实上输出了"b",也就是说changeReference()方法改变了传入引用所指对象的值。

观点1和观点2的输出结果多少会让人有些困惑,别急,我们继续往下看。

深入分析

为了详细分析这个问题,把上述两段代码合起来:

下面来深入内部来详细分析一下引用和Object内部的变化。来看下面图示:

① Line AAA, 申明一个名叫fooRef,类型为Foo的引用,并见其分配给一个新的包含属性值为"f"的对象,该对象类型为Foo。

② Line DDD, 方法内部,申明了一个Foo类型的名为aRef的引用,且aRef被初始化为null。

③ Line CCC, changeReference()方法被调用后,引用aRef被分配给fooRef指向的对象。

④ Line FFF, 申明一个名叫bRef,类型为Foo的引用,并见其分配给一个新的包含属性值为"b"的对象,该对象类型为Foo。

⑤ Line EEE, 将引用aRef重新分配给了包含属性"b"的对象。此处注意,并非将fooRef重新分配,而是aRef。

⑥ Line CCC, 调用方法modifyReference(Foo cRef)后,新建了一个引用cRef并将之分配到包含该属性"f"的对象上,该对象同时被两个引用fooRef和cRef指向着。

⑦ Line DDD, cRef.setAttribute("c");将会改变cRef引用指向的包含属性"f"的对象,而该对象同时被引用fooRef指向着。

此时引用fooRef指向的对象内部属性值"f"也被重新设置为"c"。

总结

Java内部方法传参不是引用传递,而是引用本身的"值"的传递,归根结底还是值传递。将一个对象的引用fooRef传给方法的形参newRef,将给该对象新增了一个引用,相当于多了一个alias。我们可以通过这个原引用fooRef,或这是方法参数里的新引用newRef去访问、操作原对象,也可以改变参数里的引用newRef本身的值,却无法改变原引用fooRef的值。

   
2035 次浏览       19
相关文章

Java微服务新生代之Nacos
深入理解Java中的容器
Java容器详解
Java代码质量检查工具及使用案例
相关文档

Java性能优化
Spring框架
SSM框架简单简绍
从零开始学java编程经典
相关课程

高性能Java编程与系统性能优化
JavaEE架构、 设计模式及性能调优
Java编程基础到应用开发
JAVA虚拟机原理剖析
最新活动计划
LLM大模型应用与项目构建 12-26[特惠]
QT应用开发 11-21[线上]
C++高级编程 11-27[北京]
业务建模&领域驱动设计 11-15[北京]
用户研究与用户建模 11-21[北京]
SysML和EA进行系统设计建模 11-28[北京]

Java 中的中文编码问题
Java基础知识的三十个经典问答
玩转 Java Web 应用开发
使用Spring更好地处理Struts
用Eclipse开发iPhone Web应用
插件系统框架分析
更多...   

Struts+Spring+Hibernate
基于J2EE的Web 2.0应用开发
J2EE设计模式和性能调优
Java EE 5企业级架构设计
Java单元测试方法与技术
Java编程方法与技术

Struts+Spring+Hibernate/EJB+性能优化
华夏基金 ActiveMQ 原理与管理
某民航公司 Java基础编程到应用开发
某风电公司 Java 应用开发平台与迁移
日照港 J2EE应用开发技术框架与实践
某跨国公司 工作流管理JBPM
东方航空公司 高级J2EE及其前沿技术
更多...