Java方法的参数传递方式为: 值传递
Java方法的参数传递方式为: 值传递
对于基本数据类型作为参数传递时, 是"按值传递", 这点都认识很清楚. 但是, 当对象或者说引用作为参数传递, Java 的参数传递方式是"按值传递", 还是"按引用传递", 对于新接触Java的朋友来说, 可能有点难以分清. 甚至可能有些用过一段时间的朋友对此也有争议.
首先我观点是Java参数传递方式只有一种, 就是按值传递.
先看一个代码, 如下:
public class Word {
public Word(String word) {
this.str = word;
}
public String str;
public String getStr() {
return str;
}
}
public class Tester {
public static void main(String[] args) {
Tester tester=new Tester();
Word firstWord=new Word("Hello WOrld");
System.out.println("新建对象:"+firstWord.str);
tester.changeData(firstWord);
System.out.println("执行changeData后,原对象的str属性值"+firstWord.str);
}
public void changeData(Word word){
word.str="Hello Kitty";
System.out.println("更改后的值:"+word.getStr());
}
}
运行后输出为:
新建对象:Hello WOrld
changeData方法体中更改后值:Hello Kitty
执行changeData后,FirstWord对象的str属性值Hello Kitty
这里将类 firstWord 传入后, changeData 方法把 Hello World 改成了 Hello Kitty, 并且在方法体中调用 getStr方法获得确实改称了 Hello Kitty, 回到 main 函数中, 发现 firstWord 中的str 也是 Hello Kitty.
这给人感觉是把 firstWord 对象本身传给了changeData方法, 于是在方法中对word的修改后相当于是对 firstWord 的修改. 可能很多时候会想到用这个方式来 "修改"变量: 把对象作为实参传递给某个方法, 通过在方法中对形参变量的操作来改变原对像的值, 调用结束后传参的对象改变, 特别是需要有多个返回值时. 但是这样使用时要要小心了,
因为实际二者是相互独立的, 是两个不同的变量,
如图所示,假如Hello World对象地址是 @123,两个引用变量存的是这个地址:

请看下面代码:
public class Tester {
public static void main(String[] args) {
Tester tester=new Tester();
new Word("ff");
Word firstWord=new Word("Hello WOrld");
System.out.println("新建对象:"+firstWord.str);
tester.changeData(firstWord);
System.out.println("执行changeData后,FirstWord对象的str属性值"+firstWord.str);
}
public void changeData(Word word){
word.str="Hello Kitty";
System.out.println("changeData方法体中更改后值:"+word.getStr());
word.str=null;
}
}
我们在最后一行加了一句 : word.str=null; 输出结果:
新建对象:Hello WOrld
changeData方法体中更改后值:Hello Kitty
执行changeData后,FirstWord对象的str属性值null

从代码运行结果和上图可以看到, 把 word 置成 null 后, 并不会影响到 firstWord , firstWord 依然存在, 这就说明, 二者是独立的 两个 不同 变量.
可能你会说, 我又一般又不会在changeData 函数体内设置成 null, 上面方法还是没啥关系. 但请间下面的一个情形, 可能一不小心就会犯类似错误:
public class Tester {
public static void main(String[] args) {
Tester tester=new Tester();
new Word("ff");
Word firstWord=new Word("Hello WOrld");
System.out.println("新建对象:"+firstWord.str);
tester.changeData(firstWord);
System.out.println("执行changeData后,FirstWord对象的str属性值"+firstWord.str);
}
public void changeData(Word word){
word= new Word("Hello Kitty");
System.out.println("changeData方法体中更改后值:"+word.getStr());
}
}
可能有些想法是, 把 firstWord 传给了 形参 word, 接着 把word指向一个新建的 Hello Kitty, 那么firstWord 应该也指向了 Hello Kitty.
看看程序输出结果:
新建对象:Hello WOrld
changeData方法体中更改后值:Hello Kitty
执行changeData后,FirstWord对象的str属性值Hello WOrld
发现实际并不是changeData 方法后, firstWord和word都指向 Hello Kitty, firstWord 依然指向 Hello World, 这时, 如果对Java传参了解不够, 认为传递对象进函数, 在函数内形参进行设计好的算法操作后,可以获得改变后的对象. 在这里, 就发现并不能实现这样愿望.
如果认为 Java对象作参数时,是引用传递, 当代码写长后, 可能一不小心就会出现上面类似的错误. 而且这样错误时通常还很难察觉出来.
如上面所述, 实际上对象作为参数传递时, 传递的仍然是 "值":
在mian函数中, new Word("Hello WOrld") 语句创建了 firstWord对象, 并且定义了叫 firstWord 的"引用变量" 来指向该对象(firstWord引用变量所存的是new Word("Hello WOrld") 对象的地址, 这和基本数据类型int是一样的, 只不过 int 存数值, 引用变量存地址). 传参时, 实际是把firstWord变量所存的地址值 复制了一份, 给了形参 word, 这时候他们都指向了同一个对象, 因此在 word 中更改的对象与 firstWord指向的是同一个对象, 所以这时更改会影响 firstWord. 但是word 和 firstWord 是相互独立的两个变量, 这和 C 语言中引用传递时指针的机制是不同的.
如下图所示:

Java方法的参数传递方式为: 值传递的更多相关文章
- JAVA方法中参数到底是值传递还是引用传递
当一个对象被当作参数传递到一个方法后,在此方法内可以改变这个对象的属性,那么这里到底是值传递还是引用传递? 答:是值传递.Java 语言的参数传递只有值传递.当一个实例对象作为参数被传递到方法中时,参 ...
- java方法参数传递方式只有----值传递!
在通常的说法中,方法参数的传递分为两种,值传递和引用传递,值传递是指将实际参数复制一份传递到方法中, 在方法中的改动将不会影响到实际参数本身,而引用传递则是指传递的是实际参数本身,在方法中的改动将会影 ...
- java中方法传入参数时:值传递还是址传递?
JAVA中的数据类型有两大类型: ① 基本数据类型:逻辑型(boolean).文本型(char).整数型(byte.short.int.long).浮点型(float.double) ② 引用数据类型 ...
- 关于Java方法的参数
刚好看到C++的函数这块,说C++中除了引用类型的形参,其他都是实参的副本(个人总结). 隐约记得Java中方法的参数也是这么回事,于是手动测试一番. 结果 Java中方法的参数都是值传递,哪怕是引用 ...
- 辨析Java方法参数中的值传递和引用传递
小方法大门道 小瓜瓜作为一个Java初学者,今天跟我说她想通过一个Java方法,将外部变量通过参数传递到方法中去,进行逻辑处理,方法执行完毕之后,再对修改过的变量进行判断处理,代码如下所示. publ ...
- Java里方法的参数传递方式
Java里方法的参数传递方式只有一种:值传递. Java中参数传递的都是参数值 下面从两个维度来看 1.传递的参数是8种基本数据类型 这个比较好理解,8种基本数据类型,作为参数时,可以理解为原来的一个 ...
- Java调用函数传递参数到底是值传递还是引用传递
今天翻看微信上有关Java技术的公众号时,看到了一篇关于Java中值传递的问题,文章讨论了在Java中调用函数进行传参的时候到底是值传递还是引用传递这个面试时会问到的问题.之前也接触过类似的问题,但只 ...
- Java当中的内存分配以及值传递问题内存解析
首先必须说明作为Java程序员对于内存只要有大致的了解就可以了,如果你对Java当中的某一个知识点在不需要分析内存分配过程的情况下可以掌握,那就大可不必去研究内存.如果你对知识点已经掌握,那么你应该把 ...
- Java 函数参数传递方式详解 分类: Java Game 2014-08-15 06:34 82人阅读 评论(0) 收藏
转:http://zzproc.iteye.com/blog/1328591 在阅读本文之前,根据自己的经验和理解,大家可以先思考并选择一下Java函数的参数传递方式: A. 是按值传递的? B. ...
随机推荐
- [Swift实际操作]七、常见概念-(2)点CGPoint和变形CGAffineTransform的使用
本文将为你演示点对象CGPoint的使用,其中CG表示来自CoreGraphic(核心图形)这个跨平台框架 首先导入需要使用的两个框架第一个框架表示界面工具框架第二个框架表示核心绘图和动画框架 imp ...
- Spring MVC+MySQL保存中文变成乱码
环境:MySQL,Spring MVC3.2.0,jQuery v2.0.3,使用JdbcTemplate访问数据库,相当于全套Spring解决方案. 现象 直接使用表单POST,或者使用jQuery ...
- easyui页面上字段排序并与后台交互
在开始对easyui里面页面上进行排序,感觉应该不怎么难,但是在操作的时候并没有那么简单,上网也查了很多进行排序的方法,最终总结出这个方法,供大家参考使用: 一.在easyui里面上只需 1.将要进行 ...
- day 53 Django form 组件 autu 组件
https://github.com/Endless-Clould/homework/tree/master/auto_zujian ---恢复内容开始--- 前情提要: Django 组件 的 fo ...
- Python 3 虚拟机端口映射 VMware
编程语言(以Python 3 为例子) 编程语言最开始就是机器语言(低级语言,计算机能认识:0101... 最底层的指令代码),学习很困难.现在用机器语言的很少,芯片厂商的技术人员来编程之外:发展下来 ...
- C#中ExecuteReader、ExecuteNonQuery、ExecuteScalar、SqlDataReader、SqlDataAdapter的区别
ExecuteNonQuery()执行命令对象的SQL语句,返回一个int 类型的变量,返回数据库操作之后影响的行数.适合用来验证对数据库进行增删改的情况. 2.ExecuteScalar()也可以执 ...
- Python2.x 中文乱码问题
Python 文件中如果未指定编码,在执行过程会出现报错: #!/usr/bin/pythonprint "你好,世界"; 以上程序执行输出结果为: File "test ...
- 利用ggplot2画出各种漂亮图片详细教程
1.Why use ggplot2 ggplot2是我见过最human friendly的画图软件,这得益于Leland Wilkinson在他的著作<The Grammar of Graphi ...
- CSS选择器详解(一)常用选择器
目录 类型选择器 类选择器 ID选择器 伪类 伪元素 类型选择器 通过类型选择器可以选择某一类型的html标签,并对其使用样式. 语法: selector {property1: value; pro ...
- ABP实战--分页排序
待完成... public async Task<DatatablesResultDto<TaskDto>> GetList(KeywordDatatablesRequestD ...