Java里只有“值传递”,没有“引用传递”。
# 谷强强 写道
值传递和引用传递,属于函数调用时参数的求值策略(Evaluation Strategy),这是对调用函数时,求值和传值的方式的描述,而非传递的内容的类型(内容指:是值类型还是引用类型,是值还是指针)。
值类型/引用类型,是用于区分两种内存分配方式,值类型在调用栈上分配,引用类型在堆上分配。(不要问我引用类型里定义个值类型成员或反之会发生什么,这不在这个本文的讨论范畴内,而且你看完之后,你应该可以自己想明白)。
值类型/引用类型描述内存分配方式,值传递/引用传递描述参数求值策略,两者之间无任何依赖或约束关系。
写道值类型/引用类型,是用于区分两种内存分配方式,值类型在调用栈上分配,引用类型在堆上分配。(不要问我引用类型里定义个值类型成员或反之会发生什么,这不在这个本文的讨论范畴内,而且你看完之后,你应该可以自己想明白)。
值类型/引用类型描述内存分配方式,值传递/引用传递描述参数求值策略,两者之间无任何依赖或约束关系。
在函数调用过程中,调用方提供实参,
这些实参可以是常量: Call(1);
也可以是变量: Call(x);
也可以是他们的组合: Call(2 * x + 1);
也可以是对其它函数的调用:Call(GetNumber());
但是所有这些实参的形式,都统称为表达式(Expression)。
求值(Evaluation)即是指对这些表达式的简化并求解其值的过程。
求值策略(值传递和引用传递)的关注的点在于,这些表达式在调用函数的过程中,求值的时机、值的形式的选取等问题。求值的时机,可以是在函数调用前,也可以是在函数调用后,由被调用者自己求值。这里所谓调用后求值,可以理解为Lazy Load或On Demand的一种求值方式。
这些实参可以是常量: Call(1);
也可以是变量: Call(x);
也可以是他们的组合: Call(2 * x + 1);
也可以是对其它函数的调用:Call(GetNumber());
但是所有这些实参的形式,都统称为表达式(Expression)。
求值(Evaluation)即是指对这些表达式的简化并求解其值的过程。
求值策略(值传递和引用传递)的关注的点在于,这些表达式在调用函数的过程中,求值的时机、值的形式的选取等问题。求值的时机,可以是在函数调用前,也可以是在函数调用后,由被调用者自己求值。这里所谓调用后求值,可以理解为Lazy Load或On Demand的一种求值方式。
求值策略 | 求值时机 | 传值方式 |
值传递(pass by value) | 调用前 | 值的副本(原始对象的副本) |
引用传递(pass by reference) | 调用前 | 原值(原始对象) |
名传递(pass by name) | 调用后 | 与值无关的一个名 |
则 值传递与引用传递 的区别:
值传递 | 引用传递 | |
根本区别 | 创建副本(copy) | 不创建副本 |
所以 | 在函数中无法改变对象 | 在函数中可以改变对象 |
写道
这里的改变不是指mutate, 而是change,指把一个变量指向另一个对象,而不是指仅仅改变属性或是成员什么的.
所以说Java是Pass by value,原因是它调用时Copy,实参不能指向另一个对象,而不是因为被传递的东西本质上是个Value.
写道
这些行为,与参数类型是值类型还是引用类型无关。
对于值传递,无论是值类型还是引用类型,都会在调用栈上创建一个副本,不同是,对于值类型而言,这个副本就是整个原始值的复制。而对于引用类型而言,由于引用类型的实例在堆中,在栈上只有它的一个引用(一般情况下是指针),其副本也只是这个引用的复制,而不是整个原始对象的复制.
这便引出了值类型和引用类型(这不是在说值传递)的最大区别:值类型用做参数会被复制,但是很多人误以为这个区别是值类型的特性。其实这是值传递带来的效果,和值类型本身没有关系。只是最终结果是这样。
综上所述,对于Java的函数调用方式最准确的描述是:参数藉由值传递方式,传递的值是个引用。
由于这个描述太绕,而且在字面上与Java总是传引用的事实冲突。于是对于Java,Python、Ruby、JavaScript等语言使用的这种求值策略,起了一个更贴切名字,叫Call by sharing。这个名字诞生于40年前。
对于值传递,无论是值类型还是引用类型,都会在调用栈上创建一个副本,不同是,对于值类型而言,这个副本就是整个原始值的复制。而对于引用类型而言,由于引用类型的实例在堆中,在栈上只有它的一个引用(一般情况下是指针),其副本也只是这个引用的复制,而不是整个原始对象的复制.
这便引出了值类型和引用类型(这不是在说值传递)的最大区别:值类型用做参数会被复制,但是很多人误以为这个区别是值类型的特性。其实这是值传递带来的效果,和值类型本身没有关系。只是最终结果是这样。
综上所述,对于Java的函数调用方式最准确的描述是:参数藉由值传递方式,传递的值是个引用。
由于这个描述太绕,而且在字面上与Java总是传引用的事实冲突。于是对于Java,Python、Ruby、JavaScript等语言使用的这种求值策略,起了一个更贴切名字,叫Call by sharing。这个名字诞生于40年前。
call-by-reference: You are able to assign a new reference to a method parameter variable in a method, and it will be visible by the caller of the method so after calling the method, the caller will get the new reference (new object).
call-by-sharing: You are able to assign a new reference to a method parameter variable in a method, BUT it will NOT be visible by the caller of the method so after calling the method, the caller will still get the same old reference which was passed as a method parameter to the method.
call-by-sharing: You are able to assign a new reference to a method parameter variable in a method, BUT it will NOT be visible by the caller of the method so after calling the method, the caller will still get the same old reference which was passed as a method parameter to the method.
Java代码
public class ReferenceTest { public static void main(String[] args) { StringBuffer str = new StringBuffer("aaa"); change1(str); System.out.println(str); // aaa change11(str); System.out.println(str); // aaabbb change12(str); System.out.println(str); // aaabbbbbb String ss = "111111"; change2(ss); System.out.println(ss); // 111111 int no = 123; change3(no); System.out.println(no); // 123 Long lon = 1000000L; change4(lon); System.out.println(lon); // 1000000 /** * 在Java中, 对于函数而言, 在函数内部可见的只有形参(实参的COPY), 实参是不可见的. 则在函数内部, 是没有任何方法能修改实参,使指向到一个新的对象. * * 因此, 如果形参是基本数据类型, 则函数执行完成后, 实参的值是不会也无法被改变的. * * 如果形参是引用类型, 则在形参指向到一个新的对象之前的修改, 都会影响到实参(因为此时形参和实参都指向到同一个对象).反之亦然. * */ } public static StringBuffer change1(StringBuffer sb) { sb = new StringBuffer("bbb"); //sb = null; return sb; } public static StringBuffer change11(StringBuffer sb) { sb.append("bbb"); return sb; } public static StringBuffer change12(StringBuffer sb) { sb.append("bbb"); sb = new StringBuffer("ccc"); sb.append("ddd"); return sb; } public static String change2(String str) { str += "1231231"; return str; } public static int change3(int num) { num += 10; return num; } public static Long change4(Long l) { l = l - 11111111111L; return l; } }
相关推荐
一般使用springjdbc、hibernate的sql查询,库获取到的数据都是List<Map<String, Object>>结果集,如果我们要转化为JavaBean,则需要做一系列的map.get(),然后obj.set()。 此工程中就是解决List<Map<String, Object>...
ArrayList<User> userList = new ArrayList<>(); // 添加用户... Intent intent = new Intent(currentActivity, TargetActivity.class); intent.putParcelableArrayListExtra("key", userList); startActivity...
1. **导入数据模型**:首先,你需要在Java后端将数据模型(包括`List<Map<String>>`)传递给FreeMarker。例如,你可以创建一个`ModelAndView`或自定义的`Map`对象,然后将数据模型放入其中。 ```java List<Map...
译 者 序<br><br><br><br> Java是Sun公司推出的新型面向对象程序设计语言。它将面向对象、平台无关性、稳固性、安全性、多线程等诸多特性集于一身,为用户提供了一个良好的程序设计环境。<br><br><br><br> Java提供...
复制传递和状态文件<br>6.4. 如何设置复制<br>6.5. 不同MySQL版本之间的复制兼容性<br>6.6. 升级复制设置<br>6.6.1. 将复制升级到5.0版<br>6.7. 复制特性和已知问题<br>6.8. 复制启动选项<br>6.9. 复制FAQ<br>6.10....
Java版精华区 <br>含java jsp及js等精华帖子合集<br>适合收藏 查询<br><br>序号 精华区主题 <br>--------------------------------<br> 1. [目录]Java教程 <br> 1. [目录]Java语言教程 <br> 2. [目录]来自java的传说...
文件夹说明 <br><br> ←admin[后台管理]<br><br> ←images[站内图片]<br><br> ←META-INF<br>javaif<br> ←uploadfiles[上传图片]<br><br> ←util_file[CSS]<br><br> ←WEB-INF[JAVABEAN和JAR包所在文件夹]<br><br>...
<br>测试用例编写规范.doc<br>概要设计说明书编写规范.doc<br>计算机源代码编写规范.doc<br>开发大纲.doc<br>配置管理规范.doc<br>配置管理计划...doc<br>JAVA编码规约.doc<br>VC编码规约.doc<br>具体语言的编程规范.rar
<br><br>本系统是WEB模式的新闻发布管理系统<br>运行环境:Tomact+JDK<br>编程模式:JSP+JavaBean+JavaServlet<br>后台数据库:MySql\Access<br><br>系统主要完成的功能如下:<br><br>管理员(后台)<br>.系统管理:用户...
<br><br>本系统是Web模式的办公自动化系统<br><br>运行环境:Tomact+JDK<br>编程模式:JSP+JavaBean+JavaServlet<br>后台数据库:MS-Access<br><br>系统主要功能简介:<br><br>.信息中心 <br><br>.内部电子邮件<br>...
387<br>5-5-3 Framework 388<br>5-5-4 通信与网络 389<br>5-5-5 应用层 389<br>5-5-6 Java Phone 390<br>5-5-7 新一代智能型手机 390<br>5-5-8 持续创新的Symbian OS v7.0 392<br>5-5-9 系统开发环境 394<br>5-6 ...
通过学习如何在它们之间传递值,你可以构建更复杂的系统,比如处理用户输入、进行计算、显示结果,甚至是与其他服务进行交互。希望这个简单的例子能帮助你理解这一过程,并激发你深入探索Java Web开发的兴趣。
<br><br>本系统是Web模式的在线考试管理系统<br><br>运行环境:Tomact+JDK<br><br>编程模式:JSP+JavaBean+JavaServlet<br><br>后台数据库:MS-Access<br><br>系统主要完成的功能如下:<br><br>.基本信息管理 考生...
<br><br>本系统是WEB模式的航空订票系统管理系统<br>运行环境:Tomact+JDK<br>编程模式:JSP+JavaBean+JavaServlet<br>后台数据库:MS-Access<br><br>系统主要完成的功能如下:<br><br> _订票信息管理功能 _客机信息...
前 言<br><br>第一篇 软件测试的原理 <br> 第1章 软件及其开发过程 <br> 第2章 软件测试的基本概念和方法 <br> 第3章 质量保证与测试策略<br> 第4章 软件测试依据和规范 <br><br>第二篇 软件测试的技术 <br> 第5...
前 言<br><br>第一篇 软件测试的原理 <br> 第1章 软件及其开发过程 <br> 第2章 软件测试的基本概念和方法 <br> 第3章 质量保证与测试策略<br> 第4章 软件测试依据和规范 <br><br>第二篇 软件测试的技术 <br> 第5...
前 言<br><br>第一篇 软件测试的原理 <br> 第1章 软件及其开发过程 <br> 第2章 软件测试的基本概念和方法 <br> 第3章 质量保证与测试策略<br> 第4章 软件测试依据和规范 <br><br>第二篇 软件测试的技术 <br> 第5...
前 言<br><br>第一篇 软件测试的原理 <br> 第1章 软件及其开发过程 <br> 第2章 软件测试的基本概念和方法 <br> 第3章 质量保证与测试策略<br> 第4章 软件测试依据和规范 <br><br>第二篇 软件测试的技术 <br> 第5...
13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递.zip13.java参数传递之引用传递....
`<include />`与`merge`标签结合使用 为了更有效地减少布局层级,可以配合`<merge>`标签使用。`<merge>`标签会删除其本身作为根节点,使得包含的视图直接成为父布局的一部分,避免了额外的ViewGroup层级,从而提高...