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. ...
随机推荐
- 频繁项集挖掘之Aprior和FPGrowth算法
频繁项集挖掘的应用多出现于购物篮分析,现介绍两种频繁项集的挖掘算法Aprior和FPGrowth,用以发现购物篮中出现频率较高的购物组合. 基础知识 项:“属性-值”对.比如啤酒2罐. 项集:项的集 ...
- Windows下的Nginx安装与配置(PHP)
因为一直用Apache作为服务器,对Apache的使用和配置已经相对熟悉,今天换了一下nginx的服务器,整个配置流程相对比较简单,php的配置没有任何变化. 主要的参考文档为 http://blog ...
- 使用win10自带邮件应用发送文件
之前的电脑装过邮件客户端,想发送文件给别人时,只需要“右键文件——发送到邮件”,就能把文件作为附件发送给对方.新电脑win10系统自带邮件客户端,所以就想直接用.但是右键发送到邮件没有关联上,用不了. ...
- python操作oracle数据库-查询
python操作oracle数据库-查询 参照文档 http://www.oracle.com/technetwork/cn/articles/dsl/mastering-oracle-python- ...
- SSH远程连接服务
一.SSH 原理图 二.SSH 原理描述 2.1:什么是SSH SSH是专门为了远程登录会话和其他网络服务提供的安全性协议,使用SSH协议可以有效的防止远程连接会话的时候出现信息泄密,在数据传输的时候 ...
- 漫谈NIO(3)之Netty实现
1.前言 上一章结合Java的NIO例子,讲解了多路IO复用的一个基本使用方法,通过实际编码加深对其理解.本章开始进入Netty的环节,前面两章都是为了Netty进行铺垫说明.此节将对比Java的NI ...
- redis配置详细解析
# redis 配置文件示例 # 当你需要为某个配置项指定内存大小的时候,必须要带上单位, # 通常的格式就是 1k 5gb 4m 等: # # 1k => 1000 bytes # 1kb = ...
- Java的Signature签名转换成.Net
Java: Signature sig = Signature.getInstance("SHA1withRSA"); sig.initSign(rsaPrivateKey); s ...
- Python -- Gui编程 -- Tkinter的使用 -- 菜单与画布
1.菜单 tkMenu.py import tkinter root = tkinter.Tk() menu = tkinter.Menu(root) submenu = tkinter.Menu(m ...
- Catalina.createDigester方法详细理解
这个方法主要设置(这个方法很重要,贵在理解,虽然还没学过设计模式..) 1.遇到<server>标签时创建StandardServer实例 设置StandardServer类内部的相关 ...