Java调用函数传递参数到底是值传递还是引用传递
今天翻看微信上有关Java技术的公众号时,看到了一篇关于Java中值传递的问题,文章讨论了在Java中调用函数进行传参的时候到底是值传递还是引用传递这个面试时会问到的问题。之前也接触过类似的问题,但只是知道是值传递,具体到为什么,一直不是太清楚。今天看了一下,算是明白了,写个博客记录一下。
首先先声明一下,在Java中函数传参是值传递,不是引用传递。要弄清楚这个问题之前要先弄清楚什么是值传递,什么是引用传递。
值传递(pass by value):是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递(pass by reference):是指在调用函数时将实际参数的地址直接传递到函数中,这样在函数中如果对参数进行修改,将影响实际参数。
请注意我红色标记的字,很关键。相信很多人对于是值传递还是引用传递都会有这样一种认识:在传递基本数据类型的时,是值传递,在传递引用数据类型时是引用传递。原因不过就是像下面这样的代码所表现出来的。
package com.wuqi.p1;
public class ValuePassTest {
public static void main(String[] args) {
int a = 1;
//传递基本数据类型,因为是将a的值传递给param,所以即便在pass函数中改变了
//参数的值,a的值还是不会变。所以我们认为在传递基本数据类型的时候是值传递
pass(a);
System.out.println("a= " + a);
}
private static void pass(int param) {
param = 2;
System.out.println("param= " + param);
}
}

package com.wuqi.p1;
import com.wuqi.p2.User;
public class PassTest2 {
public static void main(String[] args) {
User user = new User();
user.setName("wutianqi");
//传递对象,因为是将指向User的引用user传递给了param,
//在函数中param.setName会反应到真实的对象中去。因此我们
//认为在这种情况下是引用传递
pass(user);
System.out.println("my name is " + user.getName());
}
private static void pass(User param) {
param.setName("wuqi");
System.out.println("my name is " + param.getName());
}
}

包括我自己以前也是这么认为的。但是我们都没有注意到这样一个问题。请看代码
package com.wuqi.p1;
public class PassTest3 {
public static void main(String[] args) {
String name = "wutianqi";
//这里传递字符串参数,按照我们以前的观点这里应该传递的是将指向字符串的name引用
//传递给param,那么在pass函数中修改参数的值会直接影响到name引用指向的字符串
//的值,那么输出的结果依此应该是 my name is wuqi my name is wuqi
pass(name);
System.out.println("my name is " + name);
}
private static void pass(String param) {
param = "wuqi";
System.out.println("my name is " + param);
}
}
这段代码按照我们对象是引用传递的思想,输出的结果就应该是代码中所说的那样。但是真实输出的结果确实下面这样

哎呦!什么情况!颠覆了你的认知?当初看到这段代码我也是大吃一惊!这说明之前的认识是错的!
别慌!让我们在看一下值传递和引用传递的概念吧。这里我标红的字体起作用了。引用传递是直接传递引用,那么在函数中对参数进行修改将会影响到实际参数。按照这个理论,那么毫无疑问,通过上面的例子,引用传递对于Java函数参数传递来说是错误的。在看看值传的概念,值传递是将实际参数复制一份,对参数的改变不会影响到实际参数。注意复制这两个字!!!在上面的例子中,如果我们认为是复制了name引用,也就是复制了name引用的值,然后传递给param。param="wuqi",其实相当于param=new String("wuqi"),这时param指向了一个新的对象。而实际参数name还是指向原来的对象。这样的话输出的结果和正确的就对上了。这样也就证明了在Java中是值传递而不是引用传递。
对于对象来说传递的是引用的一个副本给参数,这一点要铭记!
Java调用函数传递参数到底是值传递还是引用传递的更多相关文章
- javascript学习笔记(二):定义函数、调用函数、参数、返回值、局部和全局变量
定义函数.调用函数.参数.返回值 关键字function定义函数,格式如下: function 函数名(){ 函数体 } 调用函数.参数.返回值的规则和c语言规则类似. <!DOCTYPE ht ...
- js中所有函数的参数(按值和按引用)都是按值传递的,怎么理解?
我觉着我可能对这块有点误解,所以单独开个博说下自己的理解,当然是研究后的正解了. 1,参数传递是基本类型,看个例子: function addTen(num){ num += 10; return n ...
- JS中函数的本质,定义、调用,以及函数的参数和返回值
要用面向对象的方式去编程,而不要用面向过程的方式去编程 对象是各种类型的数据的集合,可以是数字.字符串.数组.函数.对象…… 对象中的内容以键值对方式进行存储 对象要赋值给一个变量 var cat={ ...
- c&c++函数的参数和返回值的传递终结版
c++函数的参数和返回值的传递方式有三种:值传递.指针传递和引用传递. 在这之前先看几个例子: 一, int a=10; int b=a; b+=10; 此时b是a的一个拷贝,改变b的值,a并不会受到 ...
- Java千百问_05面向对象(011)_引用传递和值传递有什么差别
点击进入_很多其它_Java千百问 1.什么是值传递 值传递,是将内存空间中某个存储单元中存放的值,传送给还有一个存储单元.(java中的存储单元并不是物理内存的地址,但具有相关性) 比如: //定义 ...
- Python——变量的引用和函数的参数和返回值的传递方式
变量的引用 在python中,所有的变量都是指向地址,变量本身不保存数据,而是保存数据在内存中的地址.我们用下面的程序来理解: a = 10 print(id(a)) a = 11 print(id( ...
- Python中定义函数时参数有默认值的小陷阱
在定义函数的时候,如果函数的参数有默认值,有两种类型的参数,一种是整数,字符串这种不可变类型,另一种是列表这种可变类型,对于第一种情况没有什么特殊的地方,但是对于可变类型,有一个微妙的小陷阱. 可变类 ...
- Java调用.Net WebService参数为空解决办法 (远程)调试webservice方法 转
Java调用.Net WebService参数为空解决办法 (远程)调试webservice方法 同事遇到一个很囧的问题,java调,netwebservice的时候,调用无参数方法成功,调用有参 ...
- java 一个函数EnumMap返回多个值
java 一个函数如何返回多个值 在开发过程中,经常会有这种情况,就是一个函数需要返回多个值,这是一个问题!! 网上这个问题的解决方法: 1.使用map返回值:这个方法问题是,你并不知道如何返回值 ...
随机推荐
- 设计模式——迭代器(Iterator)模式
概述 迭代器模式简单的说(按我目前的理解)就是一个类提供一个对外迭代的接口,方面调用者迭代.这个迭代接口至少包括两个方法:hasNext()--用于判断是否还有下一个,next()--用于取出下一个对 ...
- css tips —— 在css中完成国际化
前提 在日常处理国际化的时候,通常是将key通过类似intl.xx(key)转换为对应环境的文案,可是如果需要在css中加入对应逻辑应该怎么做呢(比如在after的伪元素中显示不同的文案),毕竟在cs ...
- Mac 终端命令行报错 -bash: vi: command not found
我遇到的问题与这个类似,但是我的问题也是用该博文作者方法进行中断才解决的,在此表示感谢. 前段时间在 Mac 下使用终端遇到了这个问题: appledeMacBook-Air:~ air$ vi .b ...
- 开源 E-ChartSdk 的使用方法
SVN 源码地址:http://code.taobao.org/svn/keshihua-echarts/ 1.1.如何声明 var sdk = new ChartSdk(); 1.2.加载JS中的图 ...
- App压力测试MonkeyRunner整理
压力测试结果:CRASH:崩溃,应用程序在使用过程中,非正常退出ANR:Application Not Responding 命令很多,不用死记,用到复制.粘贴就行,达到目的最重要. 简单通俗易懂点讲 ...
- Java获取未知类型对象的属性
获取未知类型对象的属性通常有两种方式: 一是通过自定义注解的方式,通过获取被注解的属性从而获取属性的值,这种方式也是Spring参数注入的重要实现手段 二是通过反射获取属性的名称,通过属性名从而获取属 ...
- IDEA运行时Information:java: Errors occurred while compiling module!
在网上找了资源 说看一下项目JDK,字符编码UTF-8,但是都不很实用,突然发现: IDEA的右下角改变字符编码的按钮,先改成GBK然后再改成UTF-8,然后就OK了. 原因:导入开源的项目的时候,你 ...
- SpringMVC之ModelAndView的 jsp值在浏览页面不显示
Tomcat运行后浏览器上显示的结果! <%@ page isELIgnored="false" %>改变后问spring mvc开发过程中, 经常会给model ad ...
- 捕获enter键盘事件绑定到登录按钮
/** *捕获enter键盘事件绑定到登录按钮 */ function keyLogin(event) { if (event.keyCode == 13) { document.getElement ...
- 转载:【Oracle 集群】RAC知识图文详细教程(三)--RAC工作原理和相关组件
文章导航 集群概念介绍(一) ORACLE集群概念和原理(二) RAC 工作原理和相关组件(三) 缓存融合技术(四) RAC 特殊问题和实战经验(五) ORACLE 11 G版本2 RAC在LINUX ...